Table of Contents: the Standard Template Library

  1. Introduction to the STL
  2. How to use the documentation
  3. Containers
    1. Concepts
      1. General concepts
        1. Container
        2. Forward Container
        3. Reversible Container
        4. Random Access Container
      2. Sequences
        1. Sequence
        2. Front Insertion Sequence
        3. Back Insertion Sequence
      3. Associative Containers
        1. Associative Container
        2. Simple Associative Container
        3. Pair Associative Container
        4. Sorted Associative Container
        5. Hashed Associative Container
        6. HashFunction
        7. Unique Associative Container
        8. Multiple Associative Container
        9. Unique Sorted Associative Container
        10. Multiple Sorted Associative Container
        11. Unique Hashed Associative Container
        12. Multiple Hashed Associative Container
    2. Container classes
      1. Sequences
        1. vector
        2. deque
        3. list
        4. slist
        5. bit_vector
      2. Associative Containers
        1. set
        2. map
        3. multiset
        4. multimap
        5. hash_set
        6. hash_map
        7. hash_multiset
        8. hash_multimap
        9. hash
      3. String package
        1. Character Traits
        2. char_traits
        3. basic_string
      4. rope
      5. Container adaptors
        1. stack
        2. queue
        3. priority_queue
      6. bitset
  4. Iterators
    1. Introduction
    2. Concepts
      1. Trivial Iterator
      2. Input Iterator
      3. Output Iterator
      4. Forward Iterator
      5. Bidirectional Iterator
      6. Random Access Iterator
    3. Iterator Tags
      1. Introduction
      2. iterator_traits
      3. iterator_category
      4. distance_type
      5. value_type
      6. Iterator tag classes
        1. input_iterator_tag
        2. output_iterator_tag
        3. forward_iterator_tag
        4. bidirectional_iterator_tag
        5. random_access_iterator_tag
      7. Iterator base classes
        1. input_iterator
        2. output_iterator
        3. forward_iterator
        4. bidirectional_iterator
        5. random_access_iterator
    4. Iterator functions
      1. distance
      2. advance
    5. Iterator classes
      1. istream_iterator
      2. ostream_iterator
      3. front_insert_iterator
      4. back_insert_iterator
      5. insert_iterator
      6. reverse_iterator
      7. reverse_bidirectional_iterator
      8. raw_storage_iterator
      9. sequence_buffer
  5. Algorithms
    1. Non-mutating algorithms
      1. for_each
      2. find
      3. find_if
      4. adjacent_find
      5. find_first_of
      6. count
      7. count_if
      8. mismatch
      9. equal
      10. search
      11. search_n
      12. find_end
    2. Mutating algorithms
      1. copy
      2. copy_n
      3. copy_backward
      4. Swap
        1. swap
        2. iter_swap
        3. swap_ranges
      5. transform
      6. Replace
        1. replace
        2. replace_if
        3. replace_copy
        4. replace_copy_if
      7. fill
      8. fill_n
      9. generate
      10. generate_n
      11. Remove
        1. remove
        2. remove_if
        3. remove_copy
        4. remove_copy_if
      12. unique
      13. unique_copy
      14. reverse
      15. reverse_copy
      16. rotate
      17. rotate_copy
      18. random_shuffle
      19. random_sample
      20. random_sample_n
      21. partition
      22. stable_partition
    3. Sorting
      1. Sort
        1. sort
        2. stable_sort
        3. partial_sort
        4. partial_sort_copy
        5. is_sorted
      2. nth_element
      3. Binary search
        1. lower_bound
        2. upper_bound
        3. equal_range
        4. binary_search
      4. merge
      5. inplace_merge
      6. Set operations on sorted ranges
        1. includes
        2. set_union
        3. set_intersection
        4. set_difference
        5. set_symmetric_difference
      7. Heap operations
        1. push_heap
        2. pop_heap
        3. make_heap
        4. sort_heap
        5. is_heap
      8. Minimum and maximum
        1. min
        2. max
        3. min_element
        4. max_element
      9. lexicographical_compare
      10. lexicographical_compare_3way
      11. next_permutation
      12. prev_permutation
    4. Generalized numeric algorithms
      1. iota
      2. accumulate
      3. inner_product
      4. partial_sum
      5. adjacent_difference
      6. power
  6. Function Objects
    1. Introduction
    2. Concepts
      1. Generator
      2. Unary Function
      3. Binary Function
      4. Adaptable Generator
      5. Adaptable Unary Function
      6. Adaptable Binary Function
      7. Predicates
        1. Predicate
        2. Binary Predicate
        3. Adaptable Predicate
        4. Adaptable Binary Predicate
        5. StrictWeakOrdering
      8. Monoid Operation
      9. Random Number Generator
    3. Predefined function objects
      1. Arithmetic operations
        1. plus
        2. minus
        3. multiplies (formerly called "times")
        4. divides
        5. modulus
        6. negate
      2. Comparisons
        1. equal_to
        2. not_equal_to
        3. less
        4. greater
        5. less_equal
        6. greater_equale
      3. Logical operations
        1. logical_and
        2. logical_or
        3. logical_not
      4. Generalized identity operations
        1. identity
        2. project1st
        3. project2nd
        4. select1st
        5. select2nd
      5. subtractive_rng
    4. Function object adaptors
      1. binder1st
      2. binder2nd
      3. ptr_fun
      4. pointer_to_unary_function
      5. pointer_to_binary_function
      6. unary_negate
      7. binary_negate
      8. unary_compose
      9. binary_compose
      10. Member function adaptors
        1. mem_fun
        2. mem_fun_ref
        3. mem_fun1
        4. mem_fun1_ref
  7. Utilities
    1. Concepts
      1. Assignable
      2. Default Constructible
      3. Equality Comparable
      4. LessThan Comparable
    2. Functions
      1. Relational Operators
    3. Classes
      1. pair
  8. Memory Allocation
    1. Classes
      1. Allocators
      2. raw_storage_iterator
    2. Functions
      1. construct
      2. destroy
      3. uninitialized_copy
      4. uninitialized_copy_n
      5. uninitialized_fill
      6. uninitialized_fill_n
      7. temporary_buffer
      8. get_temporary_buffer
      9. return_temporary_buffer
  9. Design documents
    1. Thread safety
    2. The meaning of complexity specifications
    3. Representations of strings
  10. Categorized Index
  11. Full Index
[Silicon Surf] [STL Home]
Copyright © 1999 Silicon Graphics, Inc. All Rights Reserved. TrademarkInformation


accumulate

Category: algorithms | Component type: function

Prototype

Accumulate is an overloaded name; there are actually two accumulate functions.
template <class InputIterator, class T>
T accumulate(InputIterator first, InputIterator last, T init);

template <class InputIterator, class T, class BinaryFunction>
T accumulate(InputIterator first, InputIterator last, T init,
             BinaryFunction binary_op);

Description

Accumulate is a generalization of summation: it computes the sum (or some other binary operation) of init and all of the elements in the range [first, last). [1]

The function object binary_op is not required to be either commutative or associative: the order of all of accumulate's operations is specified. The result is first initialized to init. Then, for each iterator i in [first, last), in order from beginning to end, it is updated by result = result + *i (in the first version) or result = binary_op(result, *i) (in the second version).

Definition

Defined in the standard header numeric, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

For the first version, the one that takes two arguments:
  • InputIterator is a model of Input Iterator.
  • T is a model of Assignable.
  • If x is an object of type T and y is an object of InputIterator's value type, then x + y is defined.
  • The return type of x + y is convertible to T.
For the second version, the one that takes three arguments:
  • InputIterator is a model of Input Iterator.
  • T is a model of Assignable.
  • BinaryFunction is a model of Binary Function.
  • T is convertible to BinaryFunction's first argument type.
  • The value type of InputIterator is convertible to BinaryFunction's second argument type.
  • BinaryFunction's return type is convertible to T.

Preconditions

  • [first, last) is a valid range.

Complexity

Linear. Exactly last - first invocations of the binary operation.

Example

int main()
{
  int A[] = {1, 2, 3, 4, 5};
  const int N = sizeof(A) / sizeof(int);

  cout << "The sum of all elements in A is "
       << accumulate(A, A + N, 0)
       << endl;

  cout << "The product of all elements in A is "
       << accumulate(A, A + N, 1, multiplies<int>())
       << endl;
}

Notes

[1] There are several reasons why it is important that accumulate starts with the value init. One of the most basic is that this allows accumulate to have a well-defined result even if [first, last) is an empty range: if it is empty, the return value is init. If you want to find the sum of all of the elements in [first, last), you can just pass 0 as init.

See also

inner_product, partial_sum, adjacent_difference, count


Adaptable Binary Function

Category: functors | Component type: concept

Description

An Adaptable Binary Function is a Binary Function with nested typedefs that define its argument types and result type. [1] [2] These nested typedefs make it possible to use function object adaptors.

Refinement of

Binary Function

Associated types

First argument type | F::first_argument_type | The type of F's first argument
Second argument type | F::second_argument_type | The type of F's second argument
Result type | F::result_type | The type returned when the Binary Function is called

Notation

F A type that is a model of Binary Function

Definitions

Valid expressions

None, except for those defined by Binary Function

Expression semantics

Complexity guarantees

Invariants

Models

  • plus
  • project1st
  • pointer_to_binary_function

Notes

[1] Note the implication of this: a function pointer T (*f)(X,Y) is a Binary Function, but not an Adaptable Binary Function: the expressions f::first_argument_type, f::second_argument_type, and f::result_type are nonsensical.

[2] When you define a class that is a model of Adaptable Binary Function, you must provide these typedefs. The easiest way to do this is to derive the class from the base class binary_function. This is an empty class, with no member functions or member variables; the only reason it exists is to make defining Adaptable Binary Functions more convenient. Binary_function is very similar to the base classes used by the iterator tag functions.

See also

Binary Function, Adaptable Generator, Adaptable Unary Function


Adaptable Binary Predicate

Category: functors | Component type: concept

Description

An Adaptable Binary Predicate is a Binary Predicate that is also an Adaptable Binary Function. That is, it is a Binary Function whose return type is bool, and that includes nested typedefs that define its argument types and return type.

Refinement of

Predicate, Adaptable Binary Function

Associated types

None, except for those associated with Predicate and Adaptable Binary Function.

Notation

Definitions

Valid expressions

None, except for those defined by the Predicate and Adaptable Binary Function requirements.

Expression semantics

Complexity guarantees

Invariants

Models

  • less
  • equal_to
  • logical_and
  • logical_or
  • binary_negate

Notes

See also

Binary Predicate, Predicate, Adaptable Predicate


Adaptable Generator

Category: functors | Component type: concept

Description

An Adaptable Generator is a Generator with a nested typedef that defines its result type. [1] This nested typedef makes it possible to use function object adaptors.

Refinement of

Generator

Associated types

Result type F::result_type The type returned when the Generator is called

Notation

F A type that is a model of Adaptable Generator

Definitions

Valid expressions

None, except for those defined by Generator

Expression semantics

Complexity guarantees

Invariants

Models

The STL does not include any types that are models of Adaptable Generator. An example of a user-defined Adaptable Generator is as follows.
struct counter
{
  typedef int result_type;

  counter() : n(0) {}
  result_type operator()() { return n++; }

  result_type n;
};

Notes

[1] Note the implication of this: a function pointer T (*f)() is a Generator, but not an Adaptable Generator: the expression f::result_type is nonsensical.

See also

Generator, Adaptable Unary Function, Adaptable Binary Function


Adaptable Predicate

Category: functors | Component type: concept

Description

An Adaptable Predicate is a Predicate that is also an Adaptable Unary Function. That is, it is a Unary Function whose return type is bool, and that includes nested typedefs that define its argument type and return type.

Refinement of

Predicate, Adaptable Unary Function

Associated types

None, except for those associated with Predicate and Adaptable Unary Function.

Notation

Definitions

Valid expressions

None, except for those defined by the Predicate and Adaptable Unary Function requirements.

Expression semantics

Complexity guarantees

Invariants

Models

  • logical_not
  • unary_negate

Notes

See also

Predicate, Binary Predicate, Adaptable Binary Predicate


Adaptable Unary Function

Category: functors | Component type: concept

Description

An Adaptable Unary Function is a Unary Function with nested typedefs that define its argument type and result type. [1] [2] These nested typedef make it possible to use function object adaptors.

Refinement of

Unary Function

Associated types

Argument type | F::argument_type | The type of F's argument
Result type | F::result_type | The type returned when the Unary Function is called

Notation

F A type that is a model of Unary Function

Definitions

Valid expressions

None, except for those defined by Unary Function

Expression semantics

Complexity guarantees

Invariants

Models

  • negate
  • identity
  • pointer_to_unary_function

Notes

[1] Note the implication of this: a function pointer T (*f)(X) is a Unary Function, but not an Adaptable Unary Function: the expressions f::argument_type and f::result_type are nonsensical.

[2] When you define a class that is a model of Adaptable Unary Function, you must provide these typedefs. The easiest way to do this is to derive the class from the base class unary_function. This is an empty class, with no member functions or member variables; the only reason it exists is to make defining Adaptable Unary Functions more convenient. Unary_function is very similar to the base classes used by the iterator tag functions.

See also

Unary Function, Adaptable Generator, Adaptable Binary Function


adjacent_difference

Category: algorithms | Component type: function

Prototype

Adjacent_difference is an overloaded name; there are actually two adjacent_difference functions.
template <class InputIterator, class OutputIterator>
OutputIterator adjacent_difference(InputIterator first, InputIterator last,
                                   OutputIterator result);

template <class InputIterator, class OutputIterator, class BinaryFunction>
OutputIterator adjacent_difference(InputIterator first, InputIterator last,
                                   OutputIterator result,
                                   BinaryFunction binary_op);

Description

Adjacent_difference calculates the differences of adjacent elements in the range [first, last). This is, *first is assigned to *result [1], and, for each iterator i in the range [first + 1, last), the difference of *i and *(i - 1) is assigned to *(result + (i - first)). [2]

The first version of adjacent_difference uses operator- to calculate differences, and the second version uses a user-supplied binary function. In the first version, for each iterator i in the range [first + 1, last), *i - *(i - 1) is assigned to *(result + (i - first)). In the second version, the value that is assigned to *(result + 1) is instead binary_op(*i, *(i - 1)).

Definition

Defined in the standard header numeric, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

For the first version:
  • ForwardIterator is a model of Forward Iterator.
  • OutputIterator is a model of Output Iterator.
  • If x and y are objects of ForwardIterator's value type, then x - y is defined.
  • InputIterators value type is convertible to a type in OutputIterator's set of value types.
  • The return type of x - y is convertible to a type in OutputIterator's set of value types.
For the second version:
  • ForwardIterator is a model of Forward Iterator.
  • OutputIterator is a model of Output Iterator.
  • BinaryFunction is a model of Binary Function.
  • InputIterator's value type is convertible to a BinaryFunction's first argument type and second argument type.
  • InputIterators value type is convertible to a type in OutputIterator's set of value types.
  • BinaryFunction's result type is convertible to a type in OutputIterator's set of value types.

Preconditions

  • [first, last) is a valid range.
  • [result, result + (last - first)) is a valid range.

Complexity

Linear. Zero applications of the binary operation if [first, last) is an empty range, otherwise exactly (last - first) - 1 applications.

Example

int main()
{
  int A[] = {1, 4, 9, 16, 25, 36, 49, 64, 81, 100};
  const int N = sizeof(A) / sizeof(int);
  int B[N];

  cout << "A[]:         ";
  copy(A, A + N, ostream_iterator<int>(cout, " "));
  cout << endl;

  adjacent_difference(A, A + N, B);
  cout << "Differences: ";
  copy(B, B + N, ostream_iterator<int>(cout, " "));
  cout << endl;

  cout << "Reconstruct: ";
  partial_sum(B, B + N, ostream_iterator<int>(cout, " "));
  cout << endl;
}

Notes

[1] The reason it is useful to store the value of the first element, as well as simply storing the differences, is that this provides enough information to reconstruct the input range. In particular, if addition and subtraction have the usual arithmetic definitions, then adjacent_difference and partial_sum are inverses of each other.

[2] Note that result is permitted to be the same iterator as first. This is useful for computing differences "in place".

See also

partial_sum, accumulate, inner_product, count


adjacent_find

Category: algorithms | Component type: function

Prototype

Adjacent_find is an overloaded name; there are actually two adjacent_find functions.
template <class ForwardIterator>
ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last);

template <class ForwardIterator, class BinaryPredicate>
ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last,
                              BinaryPredicate binary_pred);

Description

The first version of adjacent_find returns the first iterator i such that i and i+1 are both valid iterators in [first, last), and such that *i == *(i+1). It returns last if no such iterator exists.

The second version of adjacent_find returns the first iterator i such that i and i+1 are both valid iterators in [first, last), and such that binary_pred(*i, *(i+1)) is true. It returns last if no such iterator exists.

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

For the first version:
  • ForwardIterator is a model of Forward Iterator.
  • ForwardIterator's value type is Equality Comparable.
For the second version:
  • ForwardIterator is a model of Forward Iterator.
  • ForwardIterator's value type is convertible to BinaryPredicate's first argument type and to its second argument type.

Preconditions

  • [first, last) is a valid range.

Complexity

Linear. If first == last then no comparison are performed; otherwise, at most (last - first) - 1 comparisons.

Example

Find the first element that is greater than its successor.
int A[] = {1, 2, 3, 4, 6, 5, 7, 8};
const int N = sizeof(A) / sizeof(int);

const int* p = adjacent_find(A, A + N, greater<int>());

cout << "Element " << p - A << " is out of order: "
     << *p << " > " << *(p + 1) << "." << endl;

Notes

See also

find, mismatch, equal, search


advance

Categories: algorithms, iterators | Component type: function

Prototype

template <class InputIterator, class Distance>
void advance(InputIterator& i, Distance n);

Description

Advance(i, n) increments the iterator i by the distance n. If n > 0 it is equivalent to executing ++i n times, and if n < 0 it is equivalent to executing --i n times. If n == 0, the call has no effect.

Definition

Defined in the standard header iterator, and in the nonstandard backward-compatibility header iterator.h.

Requirements on types

  • InputIterator is a model of Input Iterator.
  • Distance is an integral type that is convertible to InputIterator's distance type.

Preconditions

  • i is nonsingular.
  • Every iterator between i and i+n (inclusive) is nonsingular.
  • If InputIterator is a model of input iterator or forward iterator, then n must be nonnegative. If InputIterator is a model of bidirectional iterator or random access iterator, then this precondition does not apply.

Complexity

Constant time if InputIterator is a model of random access iterator, otherwise linear time.

Example

list<int> L;
L.push_back(0);
L.push_back(1);

list<int>::iterator i = L.begin();
advance(i, 2);
assert(i == L.end());

Notes

See also

distance, Input iterator, Bidirectional Iterator, Random access iterator, iterator_traits, Iterator overview.


SGI STL Allocator Design

This document consists of 2 sections. The first discusses some of the decisions made in the implementation of default allocators in the SGI STL. These decisions influence both the performance of the default allocator, as well as its behavior with leak detectors.

The second section describes the original design of SGI STL allocators. The current SGI STL also supports the allocator interface in the C++ standard. The interface described here is specific to the SGI STL and cannot be used in code that must be portable to other STL implementations. Thus its use is now discouraged. The discussion is nonetheless preserved both for historical reasons, and because it exposes some of the issues surrounding the standard interface.

The SGI Default Allocator

The default allocator alloc maintains its own free lists for small objects. It uses an underlying system-provided allocator both to satisfy larger requests, and to obtain larger chunks of memory which can be subdivided into small objects. Two of the detailed design decisions have proven to be controversial, and are explained here.

Alloc obtains memory from malloc

Malloc is used as the underlying system-provided allocator. This is a minor design decision. ::operator new could also have been used. Malloc has the advantage that it allows for predictable and simple failure detection. ::operator new would have made this more complicated given the portability and thread-safety constraints, and the possibility of user provided new handlers.

Alloc does not free all memory

Memory allocated for blocks of small objects is not returned to malloc. It can only be reused by subsequent alloc::allocate requests of (approximately) the same size. Thus programs that use alloc may appear to leak memory when monitored by some simple leak detectors. This is intentional. Such "leaks" do not accumulate over time. Such "leaks" are not reported by garbage-collector-like leak detectors.

The primary design criterion for alloc was to make it no slower than the HP STL per-class allocators, but potentially thread-safe, and significantly less prone to fragmentation. Like the HP allocators, it does not maintain the necessary data structures to free entire chunks of small objects when none of the contained small objects are in use. This is an intentional choice of execution time over space use. It may not be appropriate for all programs. On many systems malloc_alloc may be more space efficient, and can be used when that is crucial.

The HP allocator design returned entire memory pools when the entire allocator was no longer needed. To allow this, it maintains a count of containers using a particular allocator. With the SGI design, this would only happen when the last container disappears, which is typically just before program exit. In most environments, this would be highly counterproductive; free would typically have to touch many long unreferenced pages just before the operating system reclaims them anyway. It would often introduce a significant delay on program exit, and would possibly page out large portions of other applications. There is nothing to be gained by this action, since the OS normally reclaims memory on program exit, and it should do so without touching that memory.

In general, we recommend that leak detection tests be run with malloc_alloc instead of alloc. This yields more precise results with GC-based detectors (e.g. Pure Atria's Purify), and it provides useful results with detectors that simply count allocations and deallocations.

No Attempt to sort free lists

The default allocator makes no special attempt to ensure that consecutively allocated objects are "close" to each other, i.e. share a cache line or a page. A deallocation request adds an object to the head of a free list, and allocations remove the last deallocated object of the appropriate size. Thus allocation and deallocation each require a minimum number of instructions.

This appears to perform very well for small applications which fit into cache. It also performs well for regular applications that deallocate consecutively allocated objects consecutively. For such applications, free lists tend to remain approximately in address order. But there are no doubt applications for which some effort invested in approximate sorting of free lists would be repayed in improved cache performance.

The Original SGI STL allocator interface

The SGI specific allocator interface is much simpler than either the HP STL one or the interface in the C++ standard. Here we outline the considerations that led to this design.

An SGI STL allocator consists of a class with 3 required member functions, all of which are static:

void * allocate(size_t n)
Allocates an object with the indicated size (in bytes). The object must be sufficiently aligned for any object of the requested size.
void deallocate(void *p, size_t n)
Deallocates the object p, which must have been allocated with the same allocator and a requested size of n.
void * reallocate(void *p, size_t old_sz, size_t new_sz)
Resize object p, previously allocated to contain old_sz bytes, so that it now contains new_sz bytes. Return a pointer to the resulting object of size new_sz. The functions either returns p, after suitably adjusting the object in-place, or it copies min(old_sz, new_sz) bytes from the old object into a newly allocated object, deallocates the old object, and returns a pointer to the new object. Note that the copy is performed bit-wise; this is usually inappropriate if the object has a user defined copy constructor or destructor. Fully generic container implementations do not normally use reallocate; however it can be a performance enhancement for certain container specializations.
A discussion of the design decisions behind this rather simple design follows:

Allocators are not templates

Our allocators operate on raw, untyped memory in the same way that C's malloc does. They know nothing about the eventual type of the object. This means that the implementor of an allocator to worry about types; allocators can deal with just bytes. We provide the simple_alloc adaptor to turn a byte-based allocator into one that allocates n objects of type T. Type-oblivious allocators have the advantage that containers do not require either template template arguments or the "rebind" mechanism in the standard.

The cost is that allocators that really do need type information (e.g. for garbage collection) become somewhat harder to implement. This can be handled in a limited way by specializing simple_alloc.

(The STL standard allocators are in fact implemented with the aid of templates. But this is done mostly so that they can be distributed easily as .h files.)

Allocators do not encapsulate pointer types

(Largely shared with SGI standard allocators. The standard allows allocators to encapsulate pointer types, but does not guarantee that standard containers are functional with allocators using nonstandard pointer types.) Unlike the HP STL, our allocators do not attempt to allow use of different pointer types. They traffic only in standard void * pointers. There were several reasons for abandoning the HP approach:
  • It is not really possible to define an alternate notion of pointer within C++ without explicit compiler support. Doing so would also require the definition of a corresponding "reference" type. But there is no class that behaves like a reference. The "." field selection operation can only be applied to a reference. A template function (e.g. max) expecting a T& will usually not work when instantiated with a proxy reference type. Even proxy pointer types are problematic. Constructors require a real this pointer, not a proxy.
  • Existing STL data structures should usually not be used in environments which require very different notions of pointers, e.g. for disk-based data structures. A disk-bases set or map would require a data structure that is much more aware of locality issues. The implementation would probably also have to deal with two different pointer types: real pointers to memory allocated temporaries and references to disk based objects. Thus even the HP STL notion of encapsulated pointer types would probably be insufficient.
  • This leaves compiler supported pointers of different sizes (e.g. DOS/win16 "far" pointers). These no longer seem to be of much interest in a general purpose library. Win32 no longer makes such distinctions. Neither do any other modern (i.e. 32- or 64-bit pointer) environments of which we are aware. The issue will probably continue to matter for low end embedded systems, but those typically require somewhat nonstandard programming environments in any case. Furthermore, the same template instantiation problems as above will apply.

There are no allocator objects

An allocator's behavior is completely determined by its type. All data members of an allocator are static.

This means that containers do not need allocator members in order to allocate memory from the proper source. This avoids unneeded space overhead and/or complexity in the container code.

It also avoids a number of tricky questions about memory allocation in operations involving multiple containers. For example, it would otherwise be unclear whether concatenation of ropes built with two different allocators should be acceptable and if so, which allocator should be used for the result.

This is occasionally a significant restriction. For example, it is not possible to arrange for different containers to allocate memory mapped to different files by passing different allocator instances to the container constructors. Instead one must use one of the following alternatives:

  • The container classes must be instantiated with different allocators, one for each file. This results in different container types. This forces containers that may be mapped to different files to have distinct type, which may be a troublesome restriction, though it also results in compile-time detection of errors that might otherwise be difficult to diagnose.
  • The containers can be instantiated with a single allocator, which can be redirected to different files by calling additional member functions. The allocator must be suitably redirected before container calls that may allocate.

Allocators allocate individual objects

(Shared with standard allocators.) Some C++ programming texts have suggested that individual classes keep a free lists of frequently allocated kinds of objects, so that most allocation requests can be satisfied from the per-class free list. When an allocation request encounters an empty free list, a potentially slower allocator (e.g. new or malloc) is called to allocate several of the required objects at once, which are then used to replenish the free list.

The HP STL was designed along these lines. Allocators were intended to be used as the slower backup allocator. Containers like list were presumed to maintain their own free list.

Based on some small experiments, this has no performance advantage over directly calling the allocate function for individual objects. In fact, the generated code is essentially the same. The default allocator we provide is easily inlined. Hence any calling overhead is eliminated. If the object size is statically known (the case in which per-class free lists may be presumed to help), the address of the free list header can also be determined by the compiler.

Per-class free lists do however have many disadvantages:

  • They introduce fragmentation. Memory in the free list for class A cannot be reused by another class B, even if only class B objects are allocated for the remainder of program execution. This is particularly unfortunate if instead of a single class A there are many instances of a template class each of which has its own free list.
  • They make it much more difficult to construct thread-safe containers. A class that maintains its own free list must ensure that allocations from different threads on behalf of different containers cannot interfere with each other. This typically means that every class must be aware of the underlying synchronization primitives. If allocators allocate individual objects, then only allocators themselves need to address this issue, and most container implementations can be independent of the threading mechanism.
  • Garbage collecting allocators are difficult to accommodate. The garbage collector will see per-class free lists as accessible memory. If pointers in these free objects are not explicitly cleared, anything they reference will also be retained by the collector, reducing the effectiveness of the collector, sometimes seriously so.

Deallocate requires size argument

We chose to require an explicit size argument, both for deallocate, and to describe the original size of the object in the reallocate call. This means that no hidden per-object space overhead is required; small objects use only the space explicitly requested by the client. Thus, even in the absence of fragmentation, space usage is the same as for per-class allocators.

This choice also removes some time overhead in the important special case of fixed-size allocation. In this case, the size of the object, and thus the address of the free-list header becomes a clearly recognizable compile-time constant. Thus the generated code should be identical to that needed by a per-class free-list allocator, even if the class requires objects of only a single size.

We include realloc-style reallocation in the interface

This is probably the most questionable design decision. It would have probably been a bit more useful to provide a version of reallocate that either changed the size of the existing object without copying or returned NULL. This would have made it directly useful for objects with copy constructors. It would also have avoided unnecessary copying in cases in which the original object had not been completely filled in.

Unfortunately, this would have prohibited use of realloc from the C library. This in turn would have added complexity to many allocator implementations, and would have made interaction with memory-debugging tools more difficult. Thus we decided against this alternative.

The actual version of reallocate is still quite useful for container specializations to specific element types. The STL implementation is starting to take advantage of that.


Allocators

Category: allocators | Component type: overview

Summary

Allocators encapsulate allocation and deallocation of memory. They provide a low-level interface that permits efficient allocation of many small objects; different allocator types represent different schemes for memory management.

Note that allocators simply allocate and deallocate memory, as opposed to creating and destroying objects. The STL also includes several low-level algorithms for manipulating uninitialized memory.

Note also that allocators do not attempt to encapsulate multiple memory models. The C++ language only defines a single memory model (the difference of two pointers, for example, is always ptrdiff_t), and this memory model is the only one that allocators support. This is a major change from the definition of allocators in the original STL. [1]

Description

The details of the allocator interface are still subject to change, and we do not guarantee that specific member functions will remain in future versions. You should think of an allocator as a "black box". That is, you may select a container's memory allocation strategy by instantiating the container template with a particular allocator [2], but you should not make any assumptions about how the container actually uses the allocator.

The available allocators are as follows. In most cases you shouldn't have to worry about the distinction: the default allocator, alloc, is usually the best choice.
alloc | The default allocator. It is thread-safe, and usually has the best performance characteristics.
pthread_alloc | A thread-safe allocator that uses a different memory pool for each thread; you can only use pthread_alloc if your operating system provides pthreads. Pthread_alloc is usually faster than alloc, especially on multiprocessor systems. It can, however, cause resource fragmentation: memory deallocated in one thread is not available for use by other threads.
single_client_alloc | A fast but thread-unsafe allocator. In programs that only have one thread, this allocator might be faster than alloc.
malloc_alloc | An allocator that simply uses the standard library function malloc. It is thread-safe but slow; the main reason why you might sometimes want to use it is to get more useful information from bounds-checking or leak-detection tools while you are debugging.

Examples

vector<double> V(100, 5.0);     // Uses the default allocator.
vector<double, single_client_alloc> local(V.begin(), V.end());

Concepts

  • Allocator

Types

  • alloc
  • pthread_alloc
  • single_client_alloc
  • malloc_alloc
  • raw_storage_iterator

Functions

  • construct
  • destroy
  • uninitialized_copy
  • uninitialized_fill
  • uninitialized_fill_n
  • get_temporary_buffer
  • return_temporary_buffer

Notes

[1] The reason for this change is that the new interface reduces memory fragmentation, and that it allows an implementation that is both efficient and thread-safe.

[2] Different containers may use different allocators. You might, for example, have some containers that use the default allocator alloc and others that use pthread_alloc. Note, however, that vector<int> and vector<int, pthread_alloc> are distinct types.

See also

[Silicon Surf] [STL Home]
Copyright © 1999 Silicon Graphics, Inc. All Rights Reserved. TrademarkInformation


Assignable

Category: utilities | Component type: concept

Description

A type is Assignable if it is possible to copy objects of that type and to assign values to variables.

Refinement of

Associated types

Notation

X | A type that is a model of Assignable
x, y | Object of type X

Definitions

Valid expressions

Name | Expression | Type requirements | Return type
Copy constructor | X(x) | X
Copy constructor
X x(y);
X x = y;
Assignment | x = y [1] | X&
Swap | swap(x,y) | void

Expression semantics

Name | Expression | Precondition | Semantics | Postcondition
Copy constructor | X(x) | X(x) is a copy of x [2]
Copy constructor | X(x) | X(x) is a copy of x [2]
Copy constructor
X x(y);
X x = y;
x is a copy of y [2]
Assignment | x = y [1] | x is a copy of y [2]
Swap swap(x,y) Equivalent to
{
  X tmp = x;
  x = y;
  y = tmp;
}

Complexity guarantees

Invariants

Models

  • int

Notes

[1] One implication of this requirement is that a const type is not Assignable. For example, const int is not Assignable: if x is declared to be of type const int, then x = 7 is illegal. Similarly, the type pair<const int, int> is not Assignable.

[2] The reason this says "x is a copy of y", rather than "x == y", is that operator== is not necessarily defined: equality is not a requirement of Assignable. If the type X is EqualityComparable as well as Assignable, then a copy of x should compare equal to x.

See also

DefaultConstructible


Associative Container

Category: containers | Component type: concept

Description

An Associative Container is a variable-sized Container that supports efficient retrieval of elements (values) based on keys. It supports insertion and removal of elements, but differs from a Sequence in that it does not provide a mechanism for inserting an element at a specific position. [1]

As with all containers, the elements in an Associative Container are of type value_type. Additionally, each element in an Associative Container has a key, of type key_type. In some Associative Containers, Simple Associative Containers, the value_type and key_type are the same: elements are their own keys. In others, the key is some specific part of the value. Since elements are stored according to their keys, it is essential that the key associated with each element is immutable. In Simple Associative Containers this means that the elements themselves are immutable, while in other types of Associative Containers, such as Pair Associative Containers, the elements themselves are mutable but the part of an element that is its key cannot be modified. This means that an Associative Container's value type is not Assignable.

The fact that the value type of an Associative Container is not Assignable has an important consequence: associative containers cannot have mutable iterators. This is simply because a mutable iterator (as defined in the Trivial Iterator requirements) must allow assignment. That is, if i is a mutable iterator and t is an object of i's value type, then *i = t must be a valid expression.

In Simple Associative Containers, where the elements are the keys, the elements are completely immutable; the nested types iterator and const_iterator are therefore the same. Other types of associative containers, however, do have mutable elements, and do provide iterators through which elements can be modified. Pair Associative Containers, for example, have two different nested types iterator and const_iterator. Even in this case, iterator is not a mutable iterator: as explained above, it does not provide the expression *i = t. It is, however, possible to modify an element through such an iterator: if, for example, i is of type map<int, double>, then (*i).second = 3 is a valid expression.

In some associative containers, Unique Associative Containers, it is guaranteed that no two elements have the same key. [2] In other associative containers, Multiple Associative Containers, multiple elements with the same key are permitted.

Refinement of

Forward Container, Default Constructible

Associated types

One new type is introduced, in addition to the types defined in the Forward Container requirements.
Key type X::key_type The type of the key associated with X::value_type. Note that the key type and value type might be the same.

Notation

X | A type that is a model of Associative Container
a | Object of type X
t | Object of type X::value_type
k | Object of type X::key_type
p, q | Object of type X::iterator

Definitions

If a is an associative container, then p is a valid iterator in a if it is a valid iterator that is reachable from a.begin().

If a is an associative container, then [p, q) is a valid range in a if [p, q) is a valid range and p is a valid iterator in a.

Valid expressions

In addition to the expressions defined in Forward Container, the following expressions must be valid.
Name | Expression | Type requirements | Return type
Default constructor
X()
X a;
Erase key | a.erase(k) | size_type
Erase element | a.erase(p) | void
Erase range | a.erase(p, q) | void
Clear | a.clear() | void
Find | a.find(k) | iterator if a is mutable, otherwise const_iterator
Count | a.count(k) | size_type
Equal range | a.equal_range(k) | pair<iterator, iterator> if a is mutable, otherwise pair<const_iterator, const_iterator>.

Expression semantics

Name | Expression | Precondition | Semantics | Postcondition
Default constructor
X()
X a;
Creates an empty container. The size of the container is 0.
Erase key | a.erase(k) | Destroys all elements whose key is the same as k, and removes them from a. [2] The return value is the number of elements that were erased, i.e. the old value of a.count(k). | a.size() is decremented by a.count(k). a contains no elements with key k.
Erase element | a.erase(p) | p is a dereferenceable iterator in a. | Destroys the element pointed to by p, and removes it from a. | a.size() is decremented by 1.
Erase range | a.erase(p, q) | [p, q) is a valid range in a. | Destroys the elements in the range [p,q) and removes them from a. | a.size() is decremented by the distance from i to j.
Clear | a.clear() | Equivalent to a.erase(a.begin(), a.end())
Find | a.find(k) | Returns an iterator pointing to an element whose key is the same as k, or a.end() if no such element exists. | Either the return value is a.end(), or else the return value has a key that is the same as k.
Count | a.count(k) | Returns the number of elements in a whose keys are the same as k.
Equal range | a.equal_range(k) | Returns a pair P such that [P.first, P.second) is a range containing all elements in a whose keys are the same as k. [3] If no elements have the same key as k, the return value is an empty range. | The distance between P.first and P.second is equal to a.count(k). If p is a dereferenceable iterator in a, then either p lies in the range [P.first, P.second), or else *p has a key that is not the same as k.

Complexity guarantees

Average complexity for erase key is at most O(log(size()) + count(k)).

Average complexity for erase element is constant time.

Average complexity for erase range is at most O(log(size()) + N), where N is the number of elements in the range.

Average complexity for count is at most O(log(size()) + count(k)).

Average complexity for find is at most logarithmic.

Average complexity for equal range is at most logarithmic.

Invariants

Contiguous storage | All elements with the same key are adjacent to each other. That is, if p and q are iterators that point to elements that have the same key, and if p precedes q, then every element in the range [p, q) has the same key as every other element.
Immutability of keys | Every element of an Associative Container has an immutable key. Objects may be inserted and erased, but an element in an Associative Container may not be modified in such a way as to change its key.

Models

  • set
  • multiset
  • hash_set
  • hash_multiset
  • map
  • multimap
  • hash_map
  • hash_multimap

Notes

[1] The reason there is no such mechanism is that the way in which elements are arranged in an associative container is typically a class invariant; elements in a Sorted Associative Container, for example, are always stored in ascending order, and elements in a Hashed Associative Container are always stored according to the hash function. It would make no sense to allow the position of an element to be chosen arbitrarily.

[2] Keys are not required to be Equality Comparable: associative containers do not necessarily use operator== to determine whether two keys are the same. In Sorted Associative Containers, for example, where keys are ordered by a comparison function, two keys are considered to be the same if neither one is less than the other.

[3] Note the implications of this member function: it means that if two elements have the same key, there must be no elements with different keys in between them. The requirement that elements with the same key be stored contiguously is an associative container invariant.

See also

Simple Associative Container, Pair Associative Container, Unique Associative Container, Multiple Associative Container, Sorted Associative Container, Unique Sorted Associative Container, Multiple Sorted Associative Container, Hashed Associative Container, Unique Hashed Associative Container, Multiple Hashed Associative Container.


Back Insertion Sequence

Category: containers | Component type: concept

Description

A Back Insertion Sequence is a Sequence where it is possible to append an element to the end, or to access the last element, in amortized constant time. Back Insertion Sequences have special member functions as a shorthand for those operations.

Refinement of

Sequence

Associated types

None, except for those of Sequence.

Notation

X | A type that is a model of Back Insertion Sequence
a | Object of type X
T | The value type of X
t | Object of type T

Definitions

Valid expressions

In addition to the expressions defined in Sequence, the following expressions must be valid.
Name | Expression | Type requirements | Return type
Back | a.back() |  | reference if a is mutable, otherwise const_reference.
Push back | a.push_back(t) | a is mutable. | void
Pop back | a.pop_back() | a is mutable. | void

Expression semantics

Name | Expression | Precondition | Semantics | Postcondition
Back | a.back() | !a.empty() | Equivalent to *(--a.end()). |
Push back | a.push_back(t) |  | Equivalent to a.insert(a.end(), t) | a.size is incremented by 1. a.back() is a copy of t.
Pop back | a.pop_back() | !a.empty() | Equivalent to a.erase(--a.end()) | a.size() is decremented by 1.

Complexity guarantees

Back, push back, and pop back are amortized constant time. [1]

Invariants

Symmetry of push and pop push_back() followed by pop_back() is a null operation.

Models

  • vector
  • list
  • deque

Notes

[1] This complexity guarantee is the only reason that back(), push_back(), and pop_back() are defined: they provide no additional functionality. Not every sequence must define these operations, but it is guaranteed that they are efficient if they exist at all.

See also

Container, Sequence, Front Insertion Sequence, vector, deque, list


back_insert_iterator<BackInsertionSequence>

Categories: iterators, adaptors | Component type: type

Description

Back_insert_iterator is an iterator adaptor that functions as an Output Iterator: assignment through a back_insert_iterator inserts an object after the last element of a Back Insertion Sequence. [1]

Example

list<int> L;
L.push_front(3);
back_insert_iterator<list<int> > ii(L);
*ii++ = 0;
*ii++ = 1;
*ii++ = 2;
copy(L.begin(), L.end(), ostream_iterator<int>(cout, " "));
// The values that are printed are 3 0 1 2

Definition

Defined in the standard header iterator, and in the nonstandard backward-compatibility header iterator.h.

Template parameters

Parameter | Description | Default
BackInsertionSequence | The type of Back Insertion Sequence into which values will be inserted. |

Model of

Output Iterator. An insert iterator's set of value types (as defined in the Output Iterator requirements) consists of a single type: BackInsertionSequence::value_type.

Type requirements

The template parameter BackInsertionSequence must be a Back Insertion Sequence.

Public base classes

None.

Members

Member | Where defined | Description
back_insert_iterator(BackInsertionSequence&) | back_insert_iterator | See below.
back_insert_iterator(const back_insert_iterator&) | Trivial Iterator | The copy constructor
back_insert_iterator&
operator=(const back_insert_iterator&)
Trivial Iterator The assignment operator
back_insert_iterator& operator*() | Output Iterator | Used to implement the output iterator expression *i = x. [2]
back_insert_iterator&
operator=(const BackInsertionSequence::value_type&)
Output Iterator Used to implement the output iterator expression *i = x. [2]
back_insert_iterator& operator++() | Output Iterator | Preincrement.
back_insert_iterator& operator++(int) | Output Iterator | Postincrement.
output_iterator_tag
iterator_category(const back_insert_iterator&)
iterator tags Returns the iterator's category. This is a global function, not a member.
template<class BackInsertionSequence>
back_insert_iterator<BackInsertionSequence>
back_inserter(BackInsertionSequence& S)
back_insert_iterator See below.

New members

These members are not defined in the Output Iterator requirements, but are specific to back_insert_iterator.
Member function | Description
back_insert_iterator(BackInsertionSequence& S) | Constructs a back_insert_iterator that inserts objects after the last element of S. (That is, it inserts objects just before S's past-the-end iterator.)
template<class BackInsertionSequence>
back_insert_iterator<BackInsertionSequence>
back_inserter(BackInsertionSequence& S);
Equivalent to back_insert_iterator<BackInsertionSequence>(S). [3] This is a global function, not a member function.

Notes

[1] Note the difference between assignment through a BackInsertionSequence::iterator and assignment through a back_insert_iterator<BackInsertionSequence>. If i is a valid BackInsertionSequence::iterator, then it points to some particular element in the back insertion sequence; the expression *i = t replaces that element with t, and does not change the total number of elements in the back insertion sequence. If ii is a valid back_insert_iterator<BackInsertionSequence>, however, then the expression *ii = t is equivalent, to the expression seq.push_back(t). That is, it does not overwrite any of seq's elements and it does change seq's size.

[2] Note how assignment through a back_insert_iterator is implemented. In general, unary operator* must be defined so that it returns a proxy object, where the proxy object defines operator= to perform the insert operation. In this case, for the sake of simplicity, the proxy object is the back_insert_iterator itself. That is, *i simply returns i, and *i = t is equivalent to i = t. You should not, however, rely on this behavior. It is an implementation detail, and it is not guaranteed to remain the same in future versions.

[3] This function exists solely for the sake of convenience: since it is a non-member function, the template parameters may be inferred and the type of the back_insert_iterator need not be declared explicitly. One easy way to reverse a range and insert it at the end of a Back Insertion Sequence S, for example, is reverse_copy(first, last, back_inserter(S)).

See also

insert_iterator, front_insert_iterator, Output Iterator, Back Insertion Sequence, Sequence, Iterator overview


basic_string<charT, traits, Alloc>

Category: containers | Component type: type

Description

The basic_string class represents a Sequence of characters. It contains all the usual operations of a Sequence, and, additionally, it contains standard string operations such as search and concatenation.

The basic_string class is parameterized by character type, and by that type's Character Traits. Most of the time, however, there is no need to use the basic_string template directly. The types string and wstring are typedefs for, respectively, basic_string<char> and basic_string<wchar_t>.

Some of basic_string's member functions use an unusual method of specifying positions and ranges. In addition to the conventional method using iterators, many of basic_string's member functions use a single value pos of type size_type to represent a position (in which case the position is begin() + pos, and many of basic_string's member functions use two values, pos and n, to represent a range. In that case pos is the beginning of the range and n is its size. That is, the range is [begin() + pos, begin() + pos + n).

Note that the C++ standard does not specify the complexity of basic_string operations. In this implementation, basic_string has performance characteristics very similar to those of vector: access to a single character is O(1), while copy and concatenation are O(N). By contrast, rope has very different performance characteristics: most rope operations have logarithmic complexity.

Note also that, according to the C++ standard, basic_string has very unusual iterator invalidation semantics. Iterators may be invalidated by swap, reserve, insert, and erase (and by functions that are equivalent to insert and/or erase, such as clear, resize, append, and replace). Additionally, however, the first call to any non-const member function, including the non-const version of begin() or operator[], may invalidate iterators. (The intent of these iterator invalidation rules is to give implementors greater freedom in implementation techniques.) In this implementation, begin(), end(), rbegin(), rend(), operator[], c_str(), and data() do not invalidate iterators. In this implementation, iterators are only invalidated by member functions that explicitly change the string's contents.

Example

int main() {
  string s(10u, ' ');           // Create a string of ten blanks.

  const char* A = "this is a test";
  s += A;
  cout << "s = " << (s + '\n');
  cout << "As a null-terminated sequence: " << s.c_str() << endl;
  cout << "The sixteenth character is " << s[15] << endl;

  reverse(s.begin(), s.end());
  s.push_back('\n');
  cout << s;
}

Definition

Defined in the standard header string.

Template parameters

Parameter | Description | Default
charT | The string's value type: the type of character it contains. |
traits | The Character Traits type, which encapsulates basic character operations. | char_traits<charT>
Alloc | The string's allocator, used for internal memory management. | alloc

Model of

Random Access Container, Sequence.

Type requirements

In addition to the type requirements imposed by Random Access Container and Sequence:
  • charT is a POD ("plain ol' data") type.
  • traits is a Character Traits type whose value type is charT

Public base classes

None.

Members

Member | Where defined | Description
value_type | Container | The type of object, CharT, stored in the string.
pointer | Container | Pointer to CharT.
reference | Container | Reference to CharT
const_reference | Container | Const reference to CharT
size_type | Container | An unsigned integral type.
difference_type | Container | A signed integral type.
static const size_type npos | basic_string | The largest possible value of type size_type. That is, size_type(-1).
iterator | Container | Iterator used to iterate through a string. A basic_string supplies Random Access Iterators.
const_iterator | Container | Const iterator used to iterate through a string.
reverse_iterator | Reversible Container | Iterator used to iterate backwards through a string.
const_reverse_iterator | Reversible Container | Const iterator used to iterate backwards through a string.
iterator begin() | Container | Returns an iterator pointing to the beginning of the string.
iterator end() | Container | Returns an iterator pointing to the end of the string.
const_iterator begin() const | Container | Returns a const_iterator pointing to the beginning of the string.
const_iterator end() const | Container | Returns a const_iterator pointing to the end of the string.
reverse_iterator rbegin() | Reversible Container | Returns a reverse_iterator pointing to the beginning of the reversed string.
reverse_iterator rend() | Reversible Container | Returns a reverse_iterator pointing to the end of the reversed string.
const_reverse_iterator rbegin() const | Reversible Container | Returns a const_reverse_iterator pointing to the beginning of the reversed string.
const_reverse_iterator rend() const | Reversible Container | Returns a const_reverse_iterator pointing to the end of the reversed string.
size_type size() const | Container | Returns the size of the string.
size_type length() const | basic_string | Synonym for size().
size_type max_size() const | Container | Returns the largest possible size of the string.
size_type capacity() const | basic_string | See below.
bool empty() const | Container | true if the string's size is 0.
reference operator[](size_type n) | Random Access Container | Returns the n'th character.
const_reference operator[](size_type n) const | Random Access Container | Returns the n'th character.
const charT* c_str() const | basic_string | Returns a pointer to a null-terminated array of characters representing the string's contents.
const charT* data() const | basic_string | Returns a pointer to an array of characters (not necessarily null-terminated) representing the string's contents.
basic_string() | Container | Creates an empty string.
basic_string(const basic_string& s,
             size_type pos = 0, size_type n = npos)
Container, basic_string Generalization of the copy constructor.
basic_string(const charT*) | basic_string | Construct a string from a null-terminated character array.
basic_string(const charT* s, size_type n) | basic_string | Construct a string from a character array and a length.
basic_string(size_type n, charT c) | Sequence | Create a string with n copies of c.
template <class InputIterator>
basic_string(InputIterator first, InputIterator last)
Sequence Create a string from a range.
~basic_string() | Container | The destructor.
basic_string& operator=(const basic_string&) | Container | The assignment operator
basic_string& operator=(const charT* s) | basic_string | Assign a null-terminated character array to a string.
basic_string& operator=(charT c) | basic_string | Assign a single character to a string.
void reserve(size_t) | basic_string | See below.
void swap(basic_string&) | Container | Swaps the contents of two strings.
iterator insert(iterator pos,
                const T& x)
Sequence Inserts x before pos.
template <class InputIterator>
void insert(iterator pos,
            InputIterator f, InputIterator l)
[1]
Sequence Inserts the range [first, last) before pos.
void insert(iterator pos,
            size_type n, const T& x)
Sequence Inserts n copies of x before pos.
basic_string& insert(size_type pos, const basic_string& s) | basic_string | Inserts s before pos.
basic_string& insert(size_type pos,
                     const basic_string& s,
                     size_type pos1, size_type n)
basic_string Inserts a substring of s before pos.
basic_string& insert(size_type pos, const charT* s) | basic_string | Inserts s before pos.
basic_string& insert(size_type pos, const charT* s, size_type n) | basic_string | Inserts the first n characters of s before pos.
basic_string& insert(size_type pos, size_type n, charT c) | basic_string | Inserts n copies of c before pos.
basic_string& append(const basic_string& s) | basic_string | Append s to *this.
basic_string& append(const basic_string& s,
                     size_type pos, size_type n)
basic_string Append a substring of s to *this.
basic_string& append(const charT* s) | basic_string | Append s to *this.
basic_string& append(const charT* s, size_type n) | basic_string | Append the first n characters of s to *this.
basic_string& append(size_type n, charT c) | basic_string | Append n copies of c to *this.
template <class InputIterator>
basic_string& append(InputIterator first, InputIterator last)
basic_string Append a range to *this.
void push_back(charT c) | basic_string | Append a single character to *this.
basic_string& operator+=(const basic_string& s) | basic_string | Equivalent to append(s).
basic_string& operator+=(const charT* s) | basic_string | Equivalent to append(s)
basic_string& operator+=(charT c) | basic_string | Equivalent to push_back(c)
iterator erase(iterator p) | Sequence | Erases the character at position p
iterator erase(iterator first, iterator last) | Sequence | Erases the range [first, last)
basic_string& erase(size_type pos = 0, size_type n = npos) | basic_string | Erases a range.
void clear() | Sequence | Erases the entire container.
void resize(size_type n, charT c = charT()) | Sequence | Appends characters, or erases characters from the end, as necessary to make the string's length exactly n characters.
basic_string& assign(const basic_string&) | basic_string | Synonym for operator=

basic_string& assign(const basic_string& s,
                     size_type pos, size_type n)
basic_string Assigns a substring of s to *this
basic_string& assign(const charT* s, size_type n) | basic_string | Assigns the first n characters of s to *this.
basic_string& assign(const charT* s) | basic_string | Assigns a null-terminated array of characters to *this.
basic_string& assign(size_type n, charT c) | Sequence | Erases the existing characters and replaces them by n copies of c.
template <class InputIterator>
basic_string& assign(InputIterator first, InputIterator last)
Sequence Erases the existing characters and replaces them by [first, last)
basic_string& replace(size_type pos, size_type n,
                      const basic_string& s)
basic_string Replaces a substring of *this with the string s.
basic_string& replace(size_type pos, size_type n,
                      const basic_string& s,
                      size_type pos1, size_type n1)
basic_string Replaces a substring of *this with a substring of s.
basic_string& replace(size_type pos, size_type n,
                      const charT* s, size_type n1)
basic_string Replaces a substring of *this with the first n1 characters of s.
basic_string& replace(size_type pos, size_type n,
                      const charT* s)
basic_string Replaces a substring of *this with a null-terminated character array.
basic_string& replace(size_type pos, size_type n,
                      size_type n1, charT c)
basic_string Replaces a substring of *this with n1 copies of c.
basic_string& replace(iterator first, iterator last,
                      const basic_string& s)
basic_string Replaces a substring of *this with the string s.
basic_string& replace(iterator first, iterator last,
                      const charT* s, size_type n)
basic_string Replaces a substring of *this with the first n characters of s.
basic_string& replace(iterator first, iterator last,
                      const charT* s)
basic_string Replaces a substring of *this with a null-terminated character array.
basic_string& replace(iterator first, iterator last,
                      size_type n, charT c)
basic_string Replaces a substring of *this with n copies of c.
template <class InputIterator>
basic_string& replace(iterator first, iterator last,
                      InputIterator f, InputIterator l)
basic_string Replaces a substring of *this with the range [f, l)
size_type copy(charT* buf, size_type n, size_type pos = 0) const | basic_string | Copies a substring of *this to a buffer.
size_type find(const basic_string& s, size_type pos = 0) const | basic_string | Searches for s as a substring of *this, beginning at character pos of *this.
size_type find(const charT* s, size_type pos, size_type n) const | basic_string | Searches for the first n characters of s as a substring of *this, beginning at character pos of *this.
size_type find(const charT* s, size_type pos = 0) const | basic_string | Searches for a null-terminated character array as a substring of *this, beginning at character pos of *this.
size_type find(charT c, size_type pos = 0) const | basic_string | Searches for the character c, beginning at character position pos.
size_type rfind(const basic_string& s, size_type pos = npos) const | basic_string | Searches backward for s as a substring of *this, beginning at character position min(pos, size())
size_type rfind(const charT* s, size_type pos, size_type n) const | basic_string | Searches backward for the first n characters of s as a substring of *this, beginning at character position min(pos, size())
size_type rfind(const charT* s, size_type pos = npos) const | basic_string | Searches backward for a null-terminated character array as a substring of *this, beginning at character min(pos, size())
size_type rfind(charT c, size_type pos = npos) const | basic_string | Searches backward for the character c, beginning at character position min(pos, size().
size_type find_first_of(const basic_string& s, size_type pos = 0) const | basic_string | Searches within *this, beginning at pos, for the first character that is equal to any character within s.
size_type find_first_of(const charT* s, size_type pos, size_type n) const | basic_string | Searches within *this, beginning at pos, for the first character that is equal to any character within the first n characters of s.
size_type find_first_of(const charT* s, size_type pos = 0) const | basic_string | Searches within *this, beginning at pos, for the first character that is equal to any character within s.
size_type find_first_of(charT c, size_type pos = 0) const | basic_string | Searches within *this, beginning at pos, for the first character that is equal to c.
size_type find_first_not_of(const basic_string& s, size_type pos = 0) const | basic_string | Searches within *this, beginning at pos, for the first character that is not equal to any character within s.
size_type find_first_not_of(const charT* s, size_type pos, size_type n) const | basic_string | Searches within *this, beginning at pos, for the first character that is not equal to any character within the first n characters of s.
size_type find_first_not_of(const charT* s, size_type pos = 0) const | basic_string | Searches within *this, beginning at pos, for the first character that is not equal to any character within s.
size_type find_first_not_of(charT c, size_type pos = 0) const | basic_string | Searches within *this, beginning at pos, for the first character that is not equal to c.
size_type find_last_of(const basic_string& s, size_type pos = npos) const | basic_string | Searches backward within *this, beginning at min(pos, size()), for the first character that is equal to any character within s.
size_type find_last_of(const charT* s, size_type pos, size_type n) const | basic_string | Searches backward within *this, beginning at min(pos, size()), for the first character that is equal to any character within the first n characters of s.
size_type find_last_of(const charT* s, size_type pos = npos) const | basic_string | Searches backward *this, beginning at min(pos, size()), for the first character that is equal to any character within s.
size_type find_last_of(charT c, size_type pos = npos) const | basic_string | Searches backward *this, beginning at min(pos, size()), for the first character that is equal to c.
size_type find_last_not_of(const basic_string& s, size_type pos = npos) const | basic_string | Searches backward within *this, beginning at min(pos, size()), for the first character that is not equal to any character within s.
size_type find_last_not_of(const charT* s, size_type pos, size_type n) const | basic_string | Searches backward within *this, beginning at min(pos, size()), for the first character that is not equal to any character within the first n characters of s.
size_type find_last_not_of(const charT* s, size_type pos = npos) const | basic_string | Searches backward *this, beginning at min(pos, size()), for the first character that is not equal to any character within s.
size_type find_last_not_of(charT c, size_type pos = npos) const | basic_string | Searches backward *this, beginning at min(pos, size()), for the first character that is not equal to c.
basic_string substr(size_type pos = 0, size_type n = npos) const | basic_string | Returns a substring of *this.
int compare(const basic_string& s) const | basic_string | Three-way lexicographical comparison of s and *this.
int compare(size_type pos, size_type n, const basic_string& s) const | basic_string | Three-way lexicographical comparison of s and a substring of *this.
int compare(size_type pos, size_type n, const basic_string& s, size_type pos1, size_type n1) const | basic_string | Three-way lexicographical comparison of a substring of s and a substring of *this.
int compare(const charT* s) const | basic_string | Three-way lexicographical comparison of s and *this.
int compare(size_type pos, size_type n, const charT* s, size_type len = npos) const | basic_string | Three-way lexicographical comparison of the first min(len, traits::length(s) characters of s and a substring of *this.
template <class charT, class traits, class Alloc>
basic_string<charT, traits, Alloc>
operator+(const basic_string<charT, traits, Alloc>& s1,
          const basic_string<charT, traits, Alloc>& s2)
basic_string String concatenation. A global function, not a member function.
template <class charT, class traits, class Alloc>
basic_string<charT, traits, Alloc>
operator+(const charT* s1,
          const basic_string<charT, traits, Alloc>& s2)
basic_string String concatenation. A global function, not a member function.
template <class charT, class traits, class Alloc>
basic_string<charT, traits, Alloc>
operator+(const basic_string<charT, traits, Alloc>& s1,
          const charT* s2)
basic_string String concatenation. A global function, not a member function.
template <class charT, class traits, class Alloc>
basic_string<charT, traits, Alloc>
operator+(charT c,
          const basic_string<charT, traits, Alloc>& s2)
basic_string String concatenation. A global function, not a member function.
template <class charT, class traits, class Alloc>
basic_string<charT, traits, Alloc>
operator+(const basic_string<charT, traits, Alloc>& s1,
          charT c)
basic_string String concatenation. A global function, not a member function.
template <class charT, class traits, class Alloc>
bool operator==(const basic_string<charT, traits, Alloc>& s1,
                const basic_string<charT, traits, Alloc>& s2)
Container String equality. A global function, not a member function.
template <class charT, class traits, class Alloc>
bool operator==(const charT* s1,
                const basic_string<charT, traits, Alloc>& s2)
basic_string String equality. A global function, not a member function.
template <class charT, class traits, class Alloc>
bool operator==(const basic_string<charT, traits, Alloc>& s1,
                const charT* s2)
basic_string String equality. A global function, not a member function.
template <class charT, class traits, class Alloc>
bool operator!=(const basic_string<charT, traits, Alloc>& s1,
                const basic_string<charT, traits, Alloc>& s2)
Container String inequality. A global function, not a member function.
template <class charT, class traits, class Alloc>
bool operator!=(const charT* s1,
                const basic_string<charT, traits, Alloc>& s2)
basic_string String inequality. A global function, not a member function.
template <class charT, class traits, class Alloc>
bool operator!=(const basic_string<charT, traits, Alloc>& s1,
                const charT* s2)
basic_string String inequality. A global function, not a member function.
template <class charT, class traits, class Alloc>
bool operator<(const basic_string<charT, traits, Alloc>& s1,
               const basic_string<charT, traits, Alloc>& s2)
Container String comparison. A global function, not a member function.
template <class charT, class traits, class Alloc>
bool operator<(const charT* s1,
               const basic_string<charT, traits, Alloc>& s2)
basic_string String comparison. A global function, not a member function.
template <class charT, class traits, class Alloc>
bool operator<(const basic_string<charT, traits, Alloc>& s1,
               const charT* s2)
basic_string String comparison. A global function, not a member function.
template <class charT, class traits, class Alloc>
void swap(basic_string<charT, traits, Alloc>& s1,
          basic_string<charT, traits, Alloc>& s2)
Container Swaps the contents of two strings.
template <class charT, class traits, class Alloc>
basic_istream<charT, traits>&
operator>>(basic_istream<charT, traits>& is,
           basic_string<charT, traits, Alloc>& s)
basic_string Reads s from the input stream is
template <class charT, class traits, class Alloc>
basic_ostream<charT, traits>&
operator<<(basic_istream<charT, traits>& os,
           const basic_string<charT, traits, Alloc>& s)
basic_string Writes s to the output stream os
template <class charT, class traits, class Alloc>
basic_istream<charT, traits>&
getline(basic_istream<charT, traits>& is,
        basic_string<charT, traits, Alloc>& s,
        charT delim)
basic_string Reads a string from the input stream is, stopping when it reaches delim
template <class charT, class traits, class Alloc>
basic_istream<charT, traits>&
getline(basic_istream<charT, traits>& is,
        basic_string<charT, traits, Alloc>& s)
basic_string Reads a single line from the input stream is

New members

These members are not defined in the Random Access Container and Sequence: requirements, but are specific to basic_string.
Member | Description
static const size_type npos | The largest possible value of type size_type. That is, size_type(-1).
size_type length() const | Equivalent to size().
size_type capacity() const | Number of elements for which memory has been allocated. That is, the size to which the string can grow before memory must be reallocated. capacity() is always greater than or equal to size().
const charT* c_str() const | Returns a pointer to a null-terminated array of characters representing the string's contents. For any string s it is guaranteed that the first s.size() characters in the array pointed to by s.c_str() are equal to the character in s, and that s.c_str()[s.size()] is a null character. Note, however, that it not necessarily the first null character. Characters within a string are permitted to be null.
const charT* data() const | Returns a pointer to an array of characters, not necessarily null-terminated, representing the string's contents. data() is permitted, but not required, to be identical to c_str(). The first size() characters of that array are guaranteed to be identical to the characters in *this. The return value of data() is never a null pointer, even if size() is zero.
basic_string(const basic_string& s, size_type pos = 0, size_type n = npos) | Constructs a string from a substring of s. The substring begins at character position pos and terminates at character position pos + n or at the end of s, whichever comes first. This constructor throws out_of_range if pos > s.size(). Note that when pos and n have their default values, this is just a copy constructor.
basic_string(const charT* s) | Equivalent to basic_string(s, s + traits::length(s)).
basic_string(const charT* s, size_type n) | Equivalent to basic_string(s, s + n).
basic_string& operator=(const charT* s) | Equivalent to operator=(basic_string(s)).
basic_string& operator=(charT c) | Assigns to *this a string whose size is 1 and whose contents is the single character c.
void reserve(size_t n) | Requests that the string's capacity be changed; the postcondition for this member function is that, after it is called, capacity() >= n. You may request that a string decrease its capacity by calling reserve() with an argument less than the current capacity. (If you call reserve() with an argument less than the string's size, however, the capacity will only be reduced to size(). A string's size can never be greater than its capacity.) reserve() throws length_error if n > max_size().
basic_string& insert(size_type pos, const basic_string& s) | If pos > size(), throws out_of_range. Otherwise, equivalent to insert(begin() + pos, s.begin(), s.end()).
basic_string& insert(size_type pos,
                     const basic_string& s,
                     size_type pos1, size_type n)
If pos > size() or pos1 > s.size(), throws out_of_range. Otherwise, equivalent to insert(begin() + pos, s.begin() + pos1, s.begin() + pos1 + min(n, s.size() - pos1)).
basic_string& insert(size_type pos, const charT* s) | If pos > size(), throws out_of_range. Otherwise, equivalent to insert(begin() + pos, s, s + traits::length(s))
basic_string& insert(size_type pos, const charT* s, size_type n) | If pos > size(), throws out_of_range. Otherwise, equivalent to insert(begin() + pos, s, s + n).
basic_string& insert(size_type pos, size_type n, charT c) | If pos > size(), throws out_of_range. Otherwise, equivalent to insert(begin() + pos, n, c).
basic_string& append(const basic_string& s) | Equivalent to insert(end(), s.begin(), s.end()).
basic_string& append(const basic_string& s,
                     size_type pos, size_type n)
If pos > s.size(), throws out_of_range. Otherwise, equivalent to insert(end(), s.begin() + pos, s.begin() + pos + min(n, s.size() - pos)).
basic_string& append(const charT* s) | Equivalent to insert(end(), s, s + traits::length(s)).
basic_string& append(const charT* s, size_type n) | Equivalent to insert(end(), s, s + n).
basic_string& append(size_type n, charT c) | Equivalent to insert(end(), n, c).
template <class InputIterator>
basic_string& append(InputIterator first, InputIterator last)
Equivalent to insert(end(), first, last).
void push_back(charT c) | Equivalent to insert(end(), c)
basic_string& operator+=(const basic_string& s) | Equivalent to append(s).
basic_string& operator+=(const charT* s) | Equivalent to append(s)
basic_string& operator+=(charT c) | Equivalent to push_back(c)
basic_string& erase(size_type pos = 0, size_type n = npos) | If pos > size(), throws out_of_range. Otherwise, equivalent to erase(begin() + pos, begin() + pos + min(n, size() - pos)).
basic_string& assign(const basic_string& s) | Synonym for operator=
basic_string& assign(const basic_string& s,
                     size_type pos, size_type n)
Equivalent to (but probably faster than) clear() followed by insert(0, s, pos, n).
basic_string& assign(const charT* s, size_type n) | Equivalent to (but probably faster than) clear() followed by insert(0, s, n).
basic_string& assign(const charT* s) | Equivalent to (but probably faster than) clear() followed by insert(0, s).
basic_string& replace(size_type pos, size_type n,
                      const basic_string& s)
Equivalent to erase(pos, n) followed by insert(pos, s).
basic_string& replace(size_type pos, size_type n,
                      const basic_string& s, size_type pos1, size_type n1)
Equivalent to erase(pos, n) followed by insert(pos, s, pos1, n1).
basic_string& replace(size_type pos, size_type n,
                      const charT* s, size_type n1)
Equivalent to erase(pos, n) followed by insert(pos, s, n1).
basic_string& replace(size_type pos, size_type n,
                      const charT* s)
Equivalent to erase(pos, n) followed by insert(pos, s).
basic_string& replace(size_type pos, size_type n,
                      size_type n1, charT c)
Equivalent to erase(pos, n) followed by insert(pos, n1, c).
basic_string& replace(iterator first, iterator last,
                      const basic_string& s)
Equivalent to insert(erase(first, last), s.begin(), s.end()).
basic_string& replace(iterator first, iterator last,
                      const charT* s, size_type n)
Equivalent to insert(erase(first, last), s, s + n).
basic_string& replace(iterator first, iterator last,
                      const charT* s)
Equivalent to insert(erase(first, last), s, s + traits::length(s)).
basic_string& replace(iterator first, iterator last,
                      size_type n, charT c)
Equivalent to insert(erase(first, last), n, c).
template <class InputIterator>
basic_string& replace(iterator first, iterator last,
                      InputIterator f, InputIterator l)
Equivalent to insert(erase(first, last), f, l).
size_type copy(charT* buf, size_type n, size_type pos = 0) const | Copies at most n characters from *this to a character array. Throws out_of_range if pos > size(). Otherwise, equivalent to copy(begin() + pos, begin() + pos + min(n, size()), buf). Note that this member function does nothing other than copy characters from *this to buf; in particular, it does not terminate buf with a null character.
size_type find(const basic_string& s, size_type pos = 0) const | Searches for s as a substring of *this, beginning at character position pos. It is almost the same as search, except that search tests elements for equality using operator== or a user-provided function object, while this member function uses traits::eq. Returns the lowest character position N such that pos <= N and pos + s.size() <= size() and such that, for every i less than s.size(), (*this)[N + i] compares equal to s[i]. Returns npos if no such position N exists. Note that it is legal to call this member function with arguments such that s.size() > size() - pos, but such a search will always fail.
size_type find(const charT* s, size_type pos, size_type n) const | Searches for the first n characters of s as a substring of *this, beginning at character pos of *this. This is equivalent to find(basic_string(s, n), pos).
size_type find(const charT* s, size_type pos = 0) const | Searches for a null-terminated character array as a substring of *this, beginning at character pos of *this. This is equivalent to find(basic_string(s), pos).
size_type find(charT c, size_type pos = 0) const | Searches for the character c, beginning at character position pos. That is, returns the first character position N greater than or equal to pos, and less than size(), such that (*this)[N] compares equal to c. Returns npos if no such character position N exists.
size_type rfind(const basic_string& s, size_type pos = npos) const | Searches backward for s as a substring of *this. It is almost the same as find_end, except that find_end tests elements for equality using operator== or a user-provided function object, while this member function uses traits::eq. This member function returns the largest character position N such that N <= pos and N + s.size() <= size(), and such that, for every i less than s.size(), (*this)[N + i] compares equal to s[i]. Returns npos if no such position N exists. Note that it is legal to call this member function with arguments such that s.size() > size(), but such a search will always fail.
size_type rfind(const charT* s, size_type pos, size_type n) const | Searches backward for the first n characters of s as a substring of *this. Equivalent to rfind(basic_string(s, n), pos).
size_type rfind(const charT* s, size_type pos = npos) const | Searches backward for a null-terminated character array as a substring of *this. Equivalent to rfind(basic_string(s), pos).
size_type rfind(charT c, size_type pos = npos) const | Searches backward for the character c. That is, returns the largest character position N such that N <= pos and N < size(), and such that (*this)[N] compares equal to c. Returns npos if no such character position exists.
size_type find_first_of(const basic_string& s, size_type pos = 0) const | Searches within *this, beginning at pos, for the first character that is equal to any character within s. This is similar to the standard algorithm find_first_of, but differs because find_first_of compares characters using operator== or a user-provided function object, while this member function uses traits::eq. Returns the smallest character position N such that pos <= N < size(), and such that (*this)[N] compares equal to some character within s. Returns npos if no such character position exists.
size_type find_first_of(const charT* s, size_type pos, size_type n) const | Searches within *this, beginning at pos, for the first character that is equal to any character within the range [s, s+n). That is, returns the smallest character position N such that pos <= N < size(), and such that (*this)[N] compares equal to some character in [s, s+n). Returns npos if no such character position exists.
size_type find_first_of(const charT* s, size_type pos = 0) const | Equivalent to find_first_of(s, pos, traits::length(s)).
size_type find_first_of(charT c, size_type pos = 0) const | Equivalent to find(c, pos).
size_type find_first_not_of(const basic_string& s, size_type pos = 0) const | Searches within *this, beginning at pos, for the first character that is not equal to any character within s. Returns the smallest character position N such that pos <= N < size(), and such that (*this)[N] does not compare equal to any character within s. Returns npos if no such character position exists.
size_type find_first_not_of(const charT* s, size_type pos, size_type n) const | Searches within *this, beginning at pos, for the first character that is not equal to any character within the range [s, s+n). That is, returns the smallest character position N such that pos <= N < size(), and such that (*this)[N] does not compare equal to any character in [s, s+n). Returns npos if no such character position exists.
size_type find_first_not_of(const charT* s, size_type pos = 0) const | Equivalent to find_first_not_of(s, pos, traits::length(s)).
size_type find_first_not_of(charT c, size_type pos = 0) const | Returns the smallest character position N such that pos <= N < size(), and such that (*this)[N] does not compare equal to c. Returns npos if no such character position exists.
size_type find_last_of(const basic_string& s, size_type pos = npos) const | Searches backward within *this for the first character that is equal to any character within s. That is, returns the largest character position N such that N <= pos and N < size(), and such that (*this)[N] compares equal to some character within s. Returns npos if no such character position exists.
size_type find_last_of(const charT* s, size_type pos, size_type n) const | Searches backward within *this for the first character that is equal to any character within the range [s, s+n). That is, returns the largest character position N such that N <= pos and N < size(), and such that (*this)[N] compares equal to some character within [s, s+n). Returns npos if no such character position exists.
size_type find_last_of(const charT* s, size_type pos = npos) const | Equivalent to find_last_of(s, pos, traits::length(s)).
size_type find_last_of(charT c, size_type pos = npos) const | Equivalent to rfind(c, pos).
size_type find_last_not_of(const basic_string& s, size_type pos = npos) const | Searches backward within *this for the first character that is not equal to any character within s. That is, returns the largest character position N such that N <= pos and N < size(), and such that (*this)[N] does not compare equal to any character within s. Returns npos if no such character position exists.
size_type find_last_not_of(const charT* s, size_type pos, size_type n) const | Searches backward within *this for the first character that is not equal to any character within [s, s+n). That is, returns the largest character position N such that N <= pos and N < size(), and such that (*this)[N] does not compare equal to any character within [s, s+n). Returns npos if no such character position exists.
size_type find_last_not_of(const charT* s, size_type pos = npos) const | Equivalent to find_last_of(s, pos, traits::length(s)).
size_type find_last_not_of(charT c, size_type pos = npos) const | Searches backward *this for the first character that is not equal to c. That is, returns the largest character position N such that N <= pos and N < size(), and such that (*this)[N] does not compare equal to c.
basic_string substr(size_type pos = 0, size_type n = npos) const | Equivalent to basic_string(*this, pos, n).
int compare(const basic_string& s) const | Three-way lexicographical comparison of s and *this, much like strcmp. If traits::compare(data, s.data(), min(size(), s.size())) is nonzero, then it returns that nonzero value. Otherwise returns a negative number if size() < s.size(), a positive number if size() > s.size(), and zero if the two are equal.
int compare(size_type pos, size_type n, const basic_string& s) const | Three-way lexicographical comparison of s and a substring of *this. Equivalent to basic_string(*this, pos, n).compare(s).
int compare(size_type pos, size_type n, const basic_string& s, size_type pos1, size_type n1) const | Three-way lexicographical comparison of a substring of s and a substring of *this. Equivalent to basic_string(*this, pos, n).compare(basic_string(s, pos1, n1)).
int compare(const charT* s) const | Three-way lexicographical comparison of s and *this. Equivalent to compare(basic_string(s)).
int compare(size_type pos, size_type n, const charT* s, size_type len = npos) const | Three-way lexicographical comparison of the first min(len, traits::length(s) characters of s and a substring of *this. Equivalent to basic_string(*this, pos, n).compare(basic_string(s, min(len, traits::length(s)))).
template <class charT, class traits, class Alloc>
basic_string<charT, traits, Alloc>
operator+(const basic_string<charT, traits, Alloc>& s1,
          const basic_string<charT, traits, Alloc>& s2)
String concatenation. Equivalent to creating a temporary copy of s, appending s2, and then returning the temporary copy.
template <class charT, class traits, class Alloc>
basic_string<charT, traits, Alloc>
operator+(const charT* s1,
          const basic_string<charT, traits, Alloc>& s2)
String concatenation. Equivalent to creating a temporary basic_string object from s1, appending s2, and then returning the temporary object.
template <class charT, class traits, class Alloc>
basic_string<charT, traits, Alloc>
operator+(const basic_string<charT, traits, Alloc>& s1,
          const charT* s2)
String concatenation. Equivalent to creating a temporary copy of s, appending s2, and then returning the temporary copy.
template <class charT, class traits, class Alloc>
basic_string<charT, traits, Alloc>
operator+(charT c,
          const basic_string<charT, traits, Alloc>& s2)
String concatenation. Equivalent to creating a temporary object with the constructor basic_string(1, c), appending s2, and then returning the temporary object.
template <class charT, class traits, class Alloc>
basic_string<charT, traits, Alloc>
operator+(const basic_string<charT, traits, Alloc>& s1,
          charT c)
String concatenation. Equivalent to creating a temporary object, appending c with push_back, and then returning the temporary object.
template <class charT, class traits, class Alloc>
bool operator==(const charT* s1,
                const basic_string<charT, traits, Alloc>& s2)
String equality. Equivalent to basic_string(s1).compare(s2) == 0.
template <class charT, class traits, class Alloc>
bool operator==(const basic_string<charT, traits, Alloc>& s1,
                const charT* s2)
String equality. Equivalent to basic_string(s1).compare(s2) == 0.
template <class charT, class traits, class Alloc>
bool operator!=(const charT* s1,
                const basic_string<charT, traits, Alloc>& s2)
String inequality. Equivalent to basic_string(s1).compare(s2) == 0.
template <class charT, class traits, class Alloc>
bool operator!=(const basic_string<charT, traits, Alloc>& s1,
                const charT* s2)
String inequality. Equivalent to !(s1 == s2).
template <class charT, class traits, class Alloc>
bool operator<(const charT* s1,
               const basic_string<charT, traits, Alloc>& s2)
String comparison. Equivalent to !(s1 == s2).
template <class charT, class traits, class Alloc>
bool operator<(const basic_string<charT, traits, Alloc>& s1,
               const charT* s2)
String comparison. Equivalent to !(s1 == s2).
template <class charT, class traits, class Alloc>
basic_istream<charT, traits>&
operator>>(basic_istream<charT, traits>& is,
           basic_string<charT, traits, Alloc>& s)
Reads s from the input stream is. Specifically, it skips whitespace, and then replaces the contents of s with characters read from the input stream. It continues reading characters until it encounters a whitespace character (in which case that character is not extracted), or until end-of-file, or, if is.width() is nonzero, until it has read is.width() characters. This member function resets is.width() to zero.
template <class charT, class traits, class Alloc>
basic_ostream<charT, traits>&
operator>>(basic_istream<charT, traits>& is,
           const basic_string<charT, traits, Alloc>& s)
Writes s to the output stream is. It writes max(s.size(), is.width()) characters, padding as necessary. This member function resets is.width() to zero.
template <class charT, class traits, class Alloc>
basic_istream<charT, traits>&
getline(basic_istream<charT, traits>& is,
        basic_string<charT, traits, Alloc>& s,
        charT delim)
Replaces the contents of s with characters read from the input stream. It continues reading characters until it encounters the character delim (in which case that character is extracted but not stored in s), or until end of file. Note that getline, unlike operator>>, does not skip whitespace. As the name suggests, it is most commonly used to read an entire line of text precisely as the line appears in an input file.
template <class charT, class traits, class Alloc>
basic_istream<charT, traits>&
getline(basic_istream<charT, traits>& is,
        basic_string<charT, traits, Alloc>& s)
Equivalent to getline(is, s, is.widen('\n\)).

Notes

See also

rope, vector, Character Traits


Bidirectional Iterator

Category: iterators | Component type: concept

Description

A Bidirectional Iterator is an iterator that can be both incremented and decremented. The requirement that a Bidirectional Iterator can be decremented is the only thing that distinguishes Bidirectional Iterators from Forward Iterators.

Refinement of

Forward Iterator

Associated types

The same as for Forward Iterator.

Notation

X | A type that is a model of Bidirectional Iterator
T | The value type of X
i, j | Object of type X
t | Object of type T

Definitions

Valid expressions

In addition to the expressions defined in Forward Iterator, the following expressions must be valid.
Name | Expression | Type requirements | Return type
Predecrement | --i |  | X&
Postdecrement | i-- |  | X

Expression Semantics

Semantics of an expression is defined only where it is not defined in Forward Iterator.
Name | Expression | Precondition | Semantics | Postcondition
Predecrement | --i | i is dereferenceable or past-the-end. There exists a dereferenceable iterator j such that i == ++j. | i is modified to point to the previous element. | i is dereferenceable. &i = &--i. If i == j, then --i == --j. If j is dereferenceable and i == ++j, then --i == j.
Postdecrement i-- i is dereferenceable or past-the-end. There exists a dereferenceable iterator j such that i == ++j. Equivalent to
{
  X tmp = i;
  --i;
  return tmp;
}

Complexity guarantees

The complexity of operations on bidirectional iterators is guaranteed to be amortized constant time.

Invariants

Symmetry of increment and decrement If i is dereferenceable, then ++i; --i; is a null operation. Similarly, --i; ++i; is a null operation.

Models

  • T*
  • list<T>::iterator

Notes

See also

Input Iterator, Output Iterator, Forward Iterator, Random Access Iterator, Iterator overview


bidirectional_iterator<T, Distance>

Category: iterators | Component type: type

Description

Bidirectional_iterator is an iterator base class: it is intended that an iterator that is a model of Bidirectional Iterator, and whose value type and distance type are T and Distance, may be defined by inheriting from bidirectional_iterator<T, Distance> [1]. Bidirectional_iterator is entirely empty: it has no member functions, member variables, or nested types. It exists solely to simplify the definition of the functions iterator_category, distance_type, and value_type.

Example

class my_bidirectional_iterator : public bidirectional_iterator<double>
{
  ...
};
This declares my_bidirectional_iterator to be a Bidirectional Iterator whose value type is double and whose distance type is ptrdiff_t. If Iter is an object of class my_bidirectional_iterator, then iterator_category(Iter) will return bidirectional_iterator_tag(), value_type(Iter) will return (double*) 0, and distance_type(Iter) will return (ptrdiff_t*) 0.

Definition

Defined in the standard header iterator, and in the nonstandard backward-compatibility header iterator.h. This class is no longer part of the C++ standard, although it was present in early drafts of the standard. It is retained in this implementation for backward compatibility.

Template parameters

Parameter | Description | Default
T | The iterator's value type |
Distance | The iterator's distance type | ptrdiff_t

Model of

Assignable

Public base classes

None

Type requirements

The distance type must be a signed integral type.

Public base classes

None.

Members

None.

New Members

None.

Notes

[1] It is not required that a Bidirectional Iterator inherit from the base bidirectional_iterator. It is, however, required that the functions iterator_category, distance_type, and value_type be defined for every Bidirectional Iterator. (Or, if you are using the iterator_traits mechanism, that iterator_traits is properly specialized for every Bidirectional Iterator.) Since those functions are defined for the base bidirectional_iterator, the easiest way to ensure that are defined for a new type is to derive that class from bidirectional_iterator and rely on the derived-to-base standard conversion of function arguments.

See also

The Iterator Tags overview, iterator_traits, iterator_category, value_type, distance_type, input_iterator, output_iterator, forward_iterator, random_access_iterator


bidirectional_iterator_tag

Category: iterators | Component type: type

Description

Bidirectional_iterator_tag is an empty class: it has no member functions, member variables, or nested types. It is used solely as a "tag": a representation of the Bidirectional Iterator concept within the C++ type system. Specifically, it is used as a return value for the function iterator_category. Iterator_category takes a single argument, an iterator, and returns an object whose type depends on the iterator's category. Iterator_category's return value is of type bidirectional_iterator_tag if its argument is a Bidirectional Iterator.

Example

See iterator_category

Definition

Defined in the standard header iterator, and in the nonstandard backward-compatibility header iterator.h.

Template parameters

None.

Model of

Assignable

Type requirements

None.

Public base classes

None.

Members

None.

New Members

None.

Notes

See also

iterator_category, Iterator Tags, iterator_traits, output_iterator_tag, input_iterator_tag, forward_iterator_tag random_access_iterator_tag


Binary Function

Category: functors | Component type: concept

Description

A Binary Function is a kind of function object: an object that is called as if it were an ordinary C++ function. A Binary Function is called with two arguments.

Refinement of

Assignable

Associated types

First argument type | The type of the Binary Function's first argument.
Second argument type | The type of the Binary Function's second argument.
Result type | The type returned when the Binary Function is called

Notation

F | A type that is a model of BinaryFunction
X | The first argument type of F
Y | The second argument type of F
Result | The result type of F
f | Object of type F
x | Object of type X
y | Object of type Y

Definitions

The domain of a Binary Function is the set of all ordered pairs (x, y) that are permissible values for its arguments.

The range of a Binary Function is the set of all possible value that it may return.

Valid expressions

Name | Expression | Type requirements | Return type
Function call | f(x,y) |  | Result

Expression semantics

Name | Expression | Precondition | Semantics | Postcondition
Function call | f(x,y) | The ordered pair (x,y) is in f's domain | Calls f with x and y as arguments, and returns a value of type Result [1] | The return value is in f's range

Complexity guarantees

Invariants

Models

  • Result (*)(X,Y)

Notes

[1] Two different invocations of f may return different results, even if f is called with the same arguments both times. A Binary Function may refer to local state, perform I/O, and so on. The expression f(x,y) is permitted to change f's state.

See also

Function Object overview, Generator, Unary Function Adaptable Binary Function


Binary Predicate

Category: functors | Component type: concept

Description

A Binary Predicate is a Binary Function whose result represents the truth or falsehood of some condition. A Binary Predicate might, for example, be a function that takes two arguments and tests whether they are equal.

Refinement of

Binary Function

Associated types

Result type The type returned when the Binary Predicate is called. The result type must be convertible to bool.

Notation

F | A type that is a model of Binary Predicate
X | The first argument type of F
Y | The second argument type of F
f | Object of type F
x | Object of type X
y | Object of type Y

Valid expressions

Name | Expression | Type requirements | Return type
Function call | f(x,y) |  | Convertible to bool

Expression semantics

Name | Expression | Precondition | Semantics | Postcondition
Function call | f(x,y) | The ordered pair (x,y) is in the domain of f. | Returns true if the condition is satisfied, false if it is not. | The result is either true or false.

Complexity guarantees

Invariants

Models

  • bool (*)(int,int)
  • equal_to

Notes

See also

Predicate, Adaptable Predicate, Adaptable Binary Predicate


binary_compose<AdaptableBinaryFunction,AdaptableUnaryFunction1,AdaptableUnaryFunction2>

Categories: functors, adaptors | Component type: type

Description

Binary_compose is a function object adaptor. If f is an Adaptable Binary Function and g1 and g2 are both Adaptable Unary Functions, and if g1's and g2's return types are convertible to f's argument types, then binary_compose can be used to create a function object h such that h(x) is the same as f(g1(x), g2(x)). [1] [2]

Example

Finds the first element in a list that lies in the range from 1 to 10.
list<int> L;
...
list<int>::iterator in_range =
     find_if(L.begin(), L.end(),
             compose2(logical_and<bool>(),
                      bind2nd(greater_equal<int>(), 1),
                      bind2nd(less_equal<int>(), 10)));
assert(in_range == L.end() || (*in_range >= 1 && *in_range <= 10));

Computes sin(x)/(x + DBL_MIN) for each element of a range.

transform(first, last, first,
          compose2(divides<double>(),
                   ptr_fun(sin),
                   bind2nd(plus<double>(), DBL_MIN)));

Definition

Defined in the standard header functional, and in the nonstandard backward-compatibility header function.h. The binary_compose class is an SGI extension; it is not part of the C++ standard.

Template parameters

Parameter | Description | Default
AdaptableBinaryFunction | The type of the "outer" function in the function composition operation. That is, if the binary_compose is a function object h such that h(x) = f(g1(x), g2(x)), then AdaptableBinaryFunction is the type of f. |
AdaptableUnaryFunction1 | The type of the first "inner" function in the function composition operation. That is, if the binary_compose is a function object h such that h(x) = f(g1(x), g2(x)), then AdaptableBinaryFunction is the type of g1. |
AdaptableUnaryFunction2 | The type of the second "inner" function in the function composition operation. That is, if the binary_compose is a function object h such that h(x) = f(g1(x), g2(x)), then AdaptableBinaryFunction is the type of g2. |

Model of

Adaptable Unary Function

Type requirements

AdaptableBinaryFunction must be a model of Adaptable Binary Function. AdaptableUnaryFunction1 and AdaptableUnaryFunction2 must both be models of Adaptable Unary Function. The argument types of AdaptableUnaryFunction1 and AdaptableUnaryFunction2 must be convertible to each other. The result types of AdaptableUnaryFunction1 and AdaptableUnaryFunction2 must be convertible, respectively, to the first and second argument types of AdaptableBinaryFunction.

Public base classes

unary_function<AdaptableUnaryFunction1::argument_type,
               AdaptableBinaryFunction::result_type>

Members

Member | Where defined | Description
argument_type | Adaptable Unary Function | The type of the function object's argument: AdaptableUnaryFunction::argument_type.
result_type | Adaptable Unary Function | The type of the result: AdaptableBinaryFunction::result_type
binary_compose(const AdaptableBinaryFunction& f,
               const AdaptableUnaryFunction1& g1,
               const AdaptableUnaryFunction1& g2);
binary_compose See below.
template <class AdaptableBinaryFunction,
          class AdaptableUnaryFunction1,
          class AdaptableUnaryFunction2>
binary_compose<AdaptableBinaryFunction,
               AdaptableUnaryFunction1,
               AdaptableUnaryFunction2>
compose2(const AdaptableBinaryFunction&,
         const AdaptableUnaryFunction1&,
         const AdaptableUnaryFunction2&);
binary_compose See below.

New members

These members are not defined in the Adaptable Unary Function requirements, but are specific to binary_compose.
Member Description
binary_compose(const AdaptableBinaryFunction& f,
               const AdaptableUnaryFunction1& g1,
               const AdaptableUnaryFunction1& g2);
The constructor. Constructs a binary_compose object such that calling that object with the argument x returns f(g1(x), g2(x)).
template <class AdaptableBinaryFunction,
          class AdaptableUnaryFunction1,
          class AdaptableUnaryFunction2>
binary_compose<AdaptableBinaryFunction,
               AdaptableUnaryFunction1,
               AdaptableUnaryFunction2>
compose2(const AdaptableBinaryFunction&,
         const AdaptableUnaryFunction1&,
         const AdaptableUnaryFunction2&);
Creates a binary_compose object. If f, g, and g2 are, respectively, of classes AdaptableBinaryFunction, AdaptableUnaryFunction1, and AdaptableUnaryFunction2, then compose2(f, g1, g2) is equivalent to binary_compose<AdaptableBinaryFunction, AdaptableUnaryFunction1, AdaptableUnaryFunction2>(f, g1, g2), but is more convenient. This is a global function, not a member function.

Notes

[1] This is a form of function composition. The unary_compose adaptor allows composition of Adaptable Unary Functions; note, however, that once binary functions are introduced, there are several possible patterns of function composition. The binary_compose allows you to form a unary function by putting together two unary functions and a binary function, but you could also, for example, imagine putting together two unary functions and a binary function to form a binary function. In that case, f, g1, and g2 would be combined into a function object h such that h(x,y) = f(g1(x), g2(y)).

See also

The function object overview, unary_compose, binder1st, binder2nd.


binary_function<Arg1, Arg2, Result>

Category: functors | Component type: type

Description

Binary_function is an empty base class: it contains no member functions or member variables, but only type information. The only reason it exists is to make it more convenient to define types that are models of the concept Adaptable Binary Function. Specifically, any model of Adaptable Binary Function must define nested typedefs. Those typedefs are provided by the base class binary_function.

Example

struct exponentiate : public binary_function<double, double, double> {
    double operator()(double x, double y) { return pow(x, y); }
};

Definition

Defined in the standard header functional, and in the nonstandard backward-compatibility header function.h.

Template parameters

Parameter | Description | Default
Arg1 | The function object's first argument type |
Arg2 | The function object's second argument type |
Result | The function object's result type |

Model of

Assignable, Default Constructible

Type requirements

Public base classes

None.

Members

Member | Where defined | Description
first_argument_type | unary_function | See below.
second_argument_type | unary_function | See below.
result_type | unary_function | See below.

New members

These members are not defined in the Assignable and Default Constructible requirements, but are specific to unary_function.
Member | Description
first_argument_type | The function object's first argument type. This is a typedef for the template parameter Arg1.
second_argument_type | The function object's second argument type. This is a typedef for the template parameter Arg2.
result_type | The function object's result type. This is a typedef for the template parameter Result.

Notes

See also

The Function Object overview, Adaptable Binary Function, unary_function


binary_negate<AdaptableBinaryPredicate>

Categories: functors, adaptors | Component type: type

Description

Binary_negate is a function object adaptor: it is an Adaptable Binary Predicate that represents the logical negation of some other Adaptable Binary Predicate. That is: if f is an object of class binary_negate<AdaptableBinaryPredicate>, then there exists an object pred of class AdaptableBinaryPredicate such that f(x,y) always returns the same value as !pred(x,y). There is rarely any reason to construct a binary_negate directly; it is almost always easier to use the helper function not2.

Example

Finds the first character in a string that is neither ' ' nor '\n'.
char str[MAXLEN];
...
const char* wptr = find_if(str, str + MAXLEN,
                           compose2(not2(logical_or<bool>()),
                                    bind2nd(equal_to<char>(), ' '),
                                    bind2nd(equal_to<char>(), '\n')));
assert(wptr == str + MAXLEN || !(*wptr == ' ' || *wptr == '\n'));

Definition

Defined in the standard header functional, and in the nonstandard backward-compatibility header function.h.

Template parameters

Parameter | Description | Default
AdaptableBinaryPredicate | The type of the function object that this binary_negate is the logical negation of. |

Model of

Adaptable Binary Predicate

Type requirements

AdaptableBinaryPredicate must be a model of Adaptable Binary Predicate.

Public base classes

binary_function<AdaptableBinaryPredicate::first_argument_type,
                AdaptableBinaryPredicate::second_argument_type,
                bool>

Members

Member | Where defined | Description
first_argument_type | Adaptable Binary Function | The type of the first argument: AdaptableBinaryPredicate::first_argument_type
second_argument_type | Adaptable Binary Function | The type of the second argument: AdaptableBinaryPredicate::second_argument_type
result_type | Adaptable Binary Function | The type of the result: bool
binary_negate(const AdaptableBinaryPredicate& pred)
binary_negate See below.
template <class AdaptableBinaryPredicate>
binary_negate<AdaptableBinaryPredicate>
not2(const AdaptableBinaryPredicate& pred);
binary_negate See below.

New members

These members are not defined in the Adaptable Binary Predicate requirements, but are specific to binary_negate.
Member Description
binary_negate(const AdaptableBinaryPredicate& pred)
The constructor. Creates a binary_negate<AdaptableBinaryPredicate> whose underlying predicate is pred.
template <class AdaptableBinaryPredicate>
binary_negate<AdaptableBinaryPredicate>
not2(const AdaptableBinaryPredicate& pred);
If p is of type AdaptableBinaryPredicate then not2(p) is equivalent to binary_negate<AdaptableBinaryPredicate>(p), but more convenient. This is a global function, not a member function.

Notes

See also

The function object overview, AdaptablePredicate, Predicate, unary_negate, unary_compose, binary_compose


binary_search

Category: algorithms | Component type: function

Prototype

Binary_search is an overloaded name; there are actually two binary_search functions.
template <class ForwardIterator, class LessThanComparable>
bool binary_search(ForwardIterator first, ForwardIterator last,
                   const LessThanComparable& value);

template <class ForwardIterator, class T, class StrictWeakOrdering>
bool binary_search(ForwardIterator first, ForwardIterator last, const T& value,
                   StrictWeakOrdering comp);

Description

Binary_search is a version of binary search: it attempts to find the element value in an ordered range [first, last) It returns true if an element that is equivalent to [1] value is present in [first, last) and false if no such element exists. [2] The first version of binary_search uses operator< for comparison, and the second uses the function object comp.

Specifically, the first version returns true if and only if there exists an iterator i in [first, last) such that *i < value and value < *i are both false. The second version returns true if and only if there exists an iterator i in [first, last) such that comp(*i, value) and comp(value, *i) are both false.

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

For the first version:
  • ForwardIterator is a model of Forward Iterator.
  • LessThanComparable is a model of LessThan Comparable.
  • The ordering on objects of type LessThanComparable is a strict weak ordering, as defined in the LessThan Comparable requirements.
  • ForwardIterator's value type is the same type as LessThanComparable.
For the second version:
  • ForwardIterator is a model of Forward Iterator.
  • StrictWeakOrdering is a model of Strict Weak Ordering.
  • ForwardIterator's value type is the same type as T.
  • ForwardIterator's value type is convertible to StrictWeakOrdering's argument type.

Preconditions

For the first version:
  • [first, last) is a valid range.
  • [first, last) is ordered in ascending order according to operator<. That is, for every pair of iterators i and j in [first, last) such that i precedes j, *j < *i is false.
For the second version:
  • [first, last) is a valid range.
  • [first, last) is ordered in ascending order according to the function object comp. That is, for every pair of iterators i and j in [first, last) such that i precedes j, comp(*j, *i) is false.

Complexity

The number of comparisons is logarithmic: at most log(last - first) + 2. If ForwardIterator is a Random Access Iterator then the number of steps through the range is also logarithmic; otherwise, the number of steps is proportional to last - first. [3]

Example

int main()
{
  int A[] = { 1, 2, 3, 3, 3, 5, 8 };
  const int N = sizeof(A) / sizeof(int);

  for (int i = 1; i <= 10; ++i) {
    cout << "Searching for " << i << ": "
         << (binary_search(A, A + N, i) ? "present" : "not present") << endl;
  }
}
The output is:
Searching for 1: present
Searching for 2: present
Searching for 3: present
Searching for 4: not present
Searching for 5: present
Searching for 6: not present
Searching for 7: not present
Searching for 8: present
Searching for 9: not present
Searching for 10: not present

Notes

[1] Note that you may use an ordering that is a strict weak ordering but not a total ordering; that is, there might be values x and y such that x < y, x > y, and x == y are all false. (See the LessThan Comparable requirements for a more complete discussion.) Finding value in the range [first, last), then, doesn't mean finding an element that is equal to value but rather one that is equivalent to value: one that is neither greater than nor less than value. If you're using a total ordering, however (if you're using strcmp, for example, or if you're using ordinary arithmetic comparison on integers), then you can ignore this technical distinction: for a total ordering, equality and equivalence are the same.

[2] Note that this is not necessarily the information you are interested in! Usually, if you're testing whether an element is present in a range, you'd like to know where it is (if it's present), or where it should be inserted (if it's not present). The functions lower_bound, upper_bound, and equal_range provide this information.

[3] This difference between Random Access Iterators and Forward Iterators is simply because advance is constant time for Random Access Iterators and linear time for Forward Iterators.

See also

lower_bound, upper_bound, equal_range


binder1st<AdaptableBinaryFunction>

Categories: functors, adaptors | Component type: type

Description

Binder1st is a function object adaptor: it is used to transform an adaptable binary function into an adaptable unary function. Specifically, if f is an object of class binder1st<AdaptableBinaryFunction>, then f(x) returns F(c, x), where F is an object of class AdaptableBinaryFunction and where c is a constant. Both F and c are passed as arguments to binder1st's constructor. [1]

The easiest way to create a binder1st is not to call the constructor explicitly, but instead to use the helper function bind1st.

Example

Finds the first nonzero element in a list.
list<int> L;
...
list<int>::iterator first_nonzero =
       find_if(L.begin(), L.end(), bind1st(not_equal_to<int>(), 0));
assert(first_nonzero == L.end() || *first_nonzero != 0);

Definition

Defined in the standard header functional, and in the nonstandard backward-compatibility header function.h.

Template parameters

Parameter | Description | Default
AdaptableBinaryFunction | The type of the binary function whose first argument is being bound to a constant. |

Model of

Adaptable Unary Function

Type requirements

AdaptableBinaryFunction must be a model of Adaptable Binary Function.

Public base classes

unary_function<AdaptableBinaryFunction::second_argument_type,
               AdaptableBinaryFunction::result_type>

Members

Member | Where defined | Description
argument_type | Adaptable Unary Function | The type of the function object's argument, which is AdaptableBinaryFunction::second_argument_type
result_type | Adaptable Unary Function | The type of the result: AdaptableBinaryFunction::result_type
result_type operator()(const argument_type& x) const
Adaptable Unary Function Function call. Returns F(c, x), where F and c are the arguments with which this binder1st was constructed.
binder1st(const AdaptableBinaryFunction& F,
          AdaptableBinaryFunction::first_argument_type c)
binder1st See below
template <class AdaptableBinaryFunction, class T>
binder1st<AdaptableBinaryFunction>
bind1st(const AdaptableBinaryFunction& F, const T& c);
binder1st See below

New members

These members are not defined in the Adaptable Unary Function requirements, but are specific to binder1st.
Member Description
binder1st(const AdaptableBinaryFunction& F,
          AdaptableBinaryFunction::first_argument_type c)
The constructor. Creates a binder1st such that calling it with the argument x (where x is of type AdaptableBinaryFunction::second_argument_type) corresponds to the call F(c, x).
template <class AdaptableBinaryFunction, class T>
binder1st<AdaptableBinaryFunction>
bind1st(const AdaptableBinaryFunction& F, const T& c);
If F is an object of type AdaptableBinaryFunction, then bind1st(F, c) is equivalent to binder1st<AdaptableBinaryFunction>(F, c), but is more convenient. The type T must be convertible to AdaptableBinaryFunction::first_argument_type. This is a global function, not a member function.

Notes

[1] Intuitively, you can think of this operation as "binding" the first argument of a binary function to a constant, thus yielding a unary function. This is a special case of a closure.

See also

The function object overview, binder2nd, Adaptable Unary Function, Adaptable Binary Function


binder2nd<AdaptableBinaryFunction>

Categories: functors, adaptors | Component type: type

Description

Binder2nd is a function object adaptor: it is used to transform an adaptable binary function into an adaptable unary function. Specifically, if f is an object of class binder2nd<AdaptableBinaryFunction>, then f(x) returns F(x, c), where F is an object of class AdaptableBinaryFunction and where c is a constant. Both F and c are passed as arguments to binder2nd's constructor. [1]

The easiest way to create a binder2nd is not to call the constructor explicitly, but instead to use the helper function bind2nd.

Example

Finds the first positive number in a list.
list<int> L;
...
list<int>::iterator first_positive =
       find_if(L.begin(), L.end(), bind2nd(greater<int>(), 0));
assert(first_positive == L.end() || *first_positive > 0);

Definition

Defined in the standard header functional, and in the nonstandard backward-compatibility header function.h.

Template parameters

Parameter | Description | Default
AdaptableBinaryFunction | The type of the binary function whose second argument is being bound to a constant. |

Model of

Adaptable Unary Function

Type requirements

AdaptableBinaryFunction must be a model of Adaptable Binary Function.

Public base classes

unary_function<AdaptableBinaryFunction::first_argument_type,
               AdaptableBinaryFunction::result_type>

Members

Member | Where defined | Description
argument_type | Adaptable Unary Function | The type of the function object's argument, which is AdaptableBinaryFunction::first_argument_type
result_type | Adaptable Unary Function | The type of the result: AdaptableBinaryFunction::result_type
result_type operator()(const argument_type& x) const
Adaptable Unary Function Function call. Returns F(x, c), where F and c are the arguments with which this binder1st was constructed.
binder2nd(const AdaptableBinaryFunction& F,
          AdaptableBinaryFunction::second_argument_type c)
binder2nd See below
template <class AdaptableBinaryFunction, class T>
binder2nd<AdaptableBinaryFunction>
bind2nd(const AdaptableBinaryFunction& F, const T& c);
binder2nd See below

New members

These members are not defined in the Adaptable Unary Function requirements, but are specific to binder2nd.
Member Description
binder2nd(const AdaptableBinaryFunction& F,
          AdaptableBinaryFunction::second_argument_type c)
The constructor. Creates a binder2nd such that calling it with the argument x (where x is of type AdaptableBinaryFunction::first_argument_type) corresponds to the call F(x, c).
template <class AdaptableBinaryFunction, class T>
binder2nd<AdaptableBinaryFunction>
bind2nd(const AdaptableBinaryFunction& F, const T& c);
If F is an object of type AdaptableBinaryFunction, then bind2nd(F, c) is equivalent to binder2nd<AdaptableBinaryFunction>(F, c), but is more convenient. The type T must be convertible to AdaptableBinaryFunction::second_argument_type. This is a global function, not a member function.

[1] Intuitively, you can think of this operation as "binding" the second argument of a binary function to a constant, thus yielding a unary function. This is a special case of a closure.

See also

The function object overview, binder1st, Adaptable Unary Function, Adaptable Binary Function


bitset<N>

Category: containers | Component type: type

Description

Bitset is very similar to vector<bool> (also known as bit_vector): it contains a collection of bits, and provides constant-time access to each bit. There are two main differences between bitset and vector<bool>. First, the size of a bitset cannot be changed: bitset's template parameter N, which specifies the number of bits in the bitset, must be an integer constant. Second, bitset is not a Sequence; in fact, it is not an STL Container at all. It does not have iterators, for example, or begin() and end() member functions. Instead, bitset's interface resembles that of unsigned integers. It defines bitwise arithmetic operators such as &=, |=, and ^=.

In general, bit 0 is the least significant bit and bit N-1 is the most significant bit.

Example

int main() {
  const bitset<12> mask(2730ul);
  cout << "mask =      " << mask << endl;

  bitset<12> x;

  cout << "Enter a 12-bit bitset in binary: " << flush;
  if (cin >> x) {
    cout << "x =        " << x << endl;
    cout << "As ulong:  " << x.to_ulong() << endl;
    cout << "And with mask: " << (x & mask) << endl;
    cout << "Or with mask:  " << (x | mask) << endl;
  }
}

Definition

Defined in the standard header bitset.

Template parameters

Parameter | Description | Default
N | A nonzero constant of type size_t: the number of bits that the bitset contains. |

Model of

Assignable, Default Constructible, Equality Comparable

Type requirements

N is a constant integer expression of a type convertible to size_t, and N is a positive number.

Public base classes

None.

Members

Member | Where defined | Description
reference | bitset | A proxy class that acts as a reference to a single bit.
bitset() | Default Constructible | The default constructor. All bits are initially zero.
bitset(unsigned long val) | bitset | Conversion from unsigned long.
bitset(const bitset&) | Assignable | Copy constructor.
bitset& operator=(const bitset&) | Assignable | Assignment operator.
template<class Char, class Traits, class Alloc>
explicit
bitset(const basic_string<Char,Traits,Alloc>& s,
       size_t pos = 0,
       size_t n =
         basic_string<Char,Traits,Alloc>::npos)
bitset Conversion from string.
bitset& operator&=(const bitset&) | bitset | Bitwise and.
bitset& operator|=(const bitset&) | bitset | Bitwise inclusive or.
bitset& operator^=(const bitset&) | bitset | Bitwise exclusive or.
bitset& operator<<=(size_t) | bitset | Left shift.
bitset& operator>>=(size_t) | bitset | Right shift.
bitset operator<<(size_t n) const | bitset | Returns a copy of *this shifted left by n bits.
bitset operator>>(size_t n) const | bitset | Returns a copy of *this shifted right by n bits.
bitset& set() | bitset | Sets every bit.
bitset& flip() | bitset | Flips the value of every bit.
bitset operator~() const | bitset | Returns a copy of *this with all of its bits flipped.
bitset& reset() | bitset | Clears every bit.
bitset& set(size_t n, int val = 1) | bitset | Sets bit n if val is nonzero, and clears bit n if val is zero.
bitset& reset(size_t n) | bitset | Clears bit n.
bitset flip(size_t n) | bitset | Flips bit n.
size_t size() const | bitset | Returns N.
size_t count() const | bitset | Returns the number of bits that are set.
bool any() const | bitset | Returns true if any bits are set.
bool none() const | bitset | Returns true if no bits are set.
bool test(size_t n) const | bitset | Returns true if bit n is set.
reference operator[](size_t n) | bitset | Returns a reference to bit n.
bool operator[](size_t n) const | bitset | Returns true if bit n is set.
unsigned long to_ulong() const | bitset | Returns an unsigned long corresponding to the bits in *this.
template<class Char, class Traits, class Alloc>
basic_string<Char,Traits,Alloc> to_string() const
bitset Returns a string representation of *this.
bool operator==(const bitset&) const | Equality Comparable | The equality operator.
bool operator!=(const bitset&) const | Equality Comparable | The inequality operator.
bitset operator&(const bitset&, const bitset&) | bitset | Bitwise and of two bitsets. This is a global function, not a member function.
bitset operator|(const bitset&, const bitset&) | bitset | Bitwise or of two bitsets. This is a global function, not a member function.
bitset operator^(const bitset&, const bitset&) | bitset | Bitwise exclusive or of two bitsets. This is a global function, not a member function.
template <class Char, class Traits,
          size_t N>
basic_istream<Char,Traits>&
operator>>(basic_istream<Char,Traits>&,
           bitset<N>&)
bitset Extract a bitset from an input stream.
template <class Char, class Traits,
          size_t N>
basic_ostream<Char,Traits>&
operator>>(basic_ostream<Char,Traits>&,
           const bitset<N>&)
bitset Output a bitset to an output stream.

New members

These members are not defined in the Assignable, Default Constructible, or Equality Comparable requirements, but are specific to bitset.
Member | Description
reference | A proxy class that acts as a reference to a single bit. It contains an assignment operator, a conversion to bool, an operator~, and a member function flip. It exists only as a helper class for bitset's operator[]. That is, it supports the expressions x = b[i], b[i] = x, b[i] = b[j], x = ~b[i], and b[i].flip(). (Where b is a bitset and x is a bool.)
bitset(unsigned long val) | Conversion from unsigned long. Constructs a bitset, initializing the first min(N, sizeof(unsigned long) * CHAR_BIT) bits to the corresponding bits in val and all other bits, if any, to zero.
template<class Char, class Traits, class Alloc>
explicit
bitset(const basic_string<Char,Traits,Alloc>& s,
       size_t pos = 0,
       size_t n =
         basic_string<Char,Traits,Alloc>::npos)
Conversion from string. Constructs a bitset, initializing the first M bits to the corresponding characters in s, where M is defined as min(N, min(s.size() - pos, n)). Note that the highest character position in s, not the lowest, corresponds to the least significant bit. That is, character position pos + M - 1 - i corresponds to bit i. So, for example, bitset(string("1101")) is the same as bitset(13ul). This function throws out_of_range if pos > s.size(), and invalid_argument if any of the characters used to initialize the bits are anything other than 0 or 1.
bitset& operator&=(const bitset&) | Bitwise and.
bitset& operator|=(const bitset&) | Bitwise inclusive or.
bitset& operator^=(const bitset&) | Bitwise exclusive or.
bitset& operator<<=(size_t n) | Left shift, where bit 0 is considered the least significant bit. Bit i takes on the previous value of bit i - n, or zero if no such bit exists.
bitset& operator>>=(size_t n) | Right shift, where bit 0 is considered the least significant bit. Bit i takes on the previous value of bit i + n, or zero if no such bit exists.
bitset operator<<(size_t n) const | Returns a copy of *this shifted left by n bits. Note that the expression b << n is equivalent to constructing a temporary copy of b and then using operator<<=.
bitset operator>>(size_t n) const | Returns a copy of *this shifted right by n bits. Note that the expression b >> n is equivalent to constructing a temporary copy of b and then using operator>>=.
bitset& set() | Sets every bit.
bitset& flip() | Flips the value of every bit.
bitset operator~() const | Returns a copy of *this with all of its bits flipped.
bitset& reset() | Clears every bit.
bitset& set(size_t n, int val = 1) | Sets bit n if val is nonzero, and clears bit n if val is zero. Throws out_of_range if n >= N.
bitset& reset(size_t n) | Clears bit n. Throws out_of_range if n >= N.
bitset flip(size_t n) | Flips bit n. Throws out_of_range if n >= N.
size_t size() const | Returns N.
size_t count() const | Returns the number of bits that are set.
bool any() const | Returns true if any bits are set.
bool none() const | Returns true if no bits are set.
bool test(size_t n) const | Returns true if bit n is set. Throws out_of_range if n >= N.
reference operator[](size_t n) | Returns a reference to bit n. Note that reference is a proxy class with an assignment operator and a conversion to bool, which allows you to use operator[] for assignment. That is, you can write both x = b[n] and b[n] = x.
bool operator[](size_t n) const | Returns true if bit n is set.
unsigned long to_ulong() const | Returns an unsigned long corresponding to the bits in *this. Throws overflow_error if it is impossible to represent *this as an unsigned long. (That is, if N is larger than the number of bits in an unsigned long and if any of the high-order bits are set.
template<class Char, class Traits, class Alloc>
basic_string<Char,Traits,Alloc> to_string() const
Returns a string representation of *this: each character is 1 if the corresponding bit is set, and 0 if it is not. In general, character position i corresponds to bit position N - 1 - i. Note that this member function relies on two language features, member templates and explicit function template argument specification, that are not yet universally available; this member function is disabled for compilers that do not support those features. Note also that the syntax for calling this member function is somewhat cumbersome. To convert a bitset b to an ordinary string, you must write
b.template to_string<char, char_traits<char>, allocator<char> >()
bitset operator&(const bitset&, const bitset&) | Bitwise and of two bitsets. This is a global function, not a member function. Note that the expression b1 & b2 is equivalent to creating a temporary copy of b1, using operator&=, and returning the temporary copy.
bitset operator|(const bitset&, const bitset&) | Bitwise or of two bitsets. This is a global function, not a member function. Note that the expression b1 | b2 is equivalent to creating a temporary copy of b1, using operator|=, and returning the temporary copy.
bitset operator^(const bitset&, const bitset&) | Bitwise exclusive or of two bitsets. This is a global function, not a member function. Note that the expression b1 ^ b2 is equivalent to creating a temporary copy of b1, using operator^=, and returning the temporary copy.
template <class Char, class Traits,
          size_t N>
basic_istream<Char, Traits>&
operator>>(basic_istream<Char,Traits>& is,
           bitset<N>& x)
Extract a bitset from an input stream. This function first skips whitespace, then extracts up to N characters from the input stream. It stops either when it has successfully extracted N character, or when extraction fails, or when it sees a character that is something other than 1 (in which case it does not extract that character). It then assigns a value to the bitset in the same way as if it were initializing the bitset from a string. So, for example, if the input stream contains the characters "1100abc", it will assign the value 12ul to the bitset, and the next character read from the input stream will be a.
template <class Char, class Traits,
          size_t N>
basic_ostream<Char,Traits>&
operator>>(basic_ostream<Char,Traits>& os,
           const bitset<N>& x)
Output a bitset to an output stream. This function behaves as if it converts the bitset to a string and then writes that string to the output stream. That is, it is equivalent to
os << x.template to_string<Char,Traits,allocator<Char> >()

Notes

See also

vector, bit_vector, string


bit_vector

Category: containers | Component type: type

Description

A bit_vector is essentially a vector<bool>: it is a Sequence that has the same interface as vector. The main difference is that bit_vector is optimized for space efficiency. A vector always requires at least one byte per element, but a bit_vector only requires one bit per element.

Warning: The name bit_vector will be removed in a future release of the STL. The only reason that bit_vector is a separate class, instead of a template specialization of vector<bool>, is that this would require partial specialization of templates. On compilers that support partial specialization, bit_vector is a specialization of vector<bool>. The name bit_vector is a typedef. This typedef is not defined in the C++ standard, and is retained only for backward compatibility.

Example

bit_vector V(5);
V[0] = true;
V[1] = false;
V[2] = false;
V[3] = true;
V[4] = false;

for (bit_vector::iterator i = V.begin(); i < V.end(); ++i)
  cout << (*i ? '1' : '0');
cout << endl;

Definition

Defined in the standard header vector, and in the nonstandard backward-compatibility header bvector.h.

Template parameters

None. Bit_vector is not a class template.

Model of

Random access container, Back insertion sequence.

Type requirements

None.

Public base classes

None.

Members

Member | Where defined | Description
value_type | Container | The type of object stored in the bit_vector: bool
reference | bit_vector | A proxy class that acts as a reference to a single bit. See below for details.
const_reference | Container | Const reference to value_type. In bit_vector this is simply defined to be bool.
size_type | Container | An unsigned integral type.
difference_type | Container | A signed integral type.
iterator | Container | Iterator used to iterate through a bit_vector.
const_iterator | Container | Const iterator used to iterate through a bit_vector.
reverse_iterator | Reversible Container | Iterator used to iterate backwards through a bit_vector.
const_reverse_iterator | Reversible Container | Const iterator used to iterate backwards through a bit_vector.
iterator begin() | Container | Returns an iterator pointing to the beginning of the bit_vector.
iterator end() | Container | Returns an iterator pointing to the end of the bit_vector.
const_iterator begin() const | Container | Returns a const_iterator pointing to the beginning of the bit_vector.
const_iterator end() const | Container | Returns a const_iterator pointing to the end of the bit_vector.
reverse_iterator rbegin() | Reversible Container | Returns a reverse_iterator pointing to the beginning of the reversed bit_vector.
reverse_iterator rend() | Reversible Container | Returns a reverse_iterator pointing to the end of the reversed bit_vector.
const_reverse_iterator rbegin() const | Reversible Container | Returns a const_reverse_iterator pointing to the beginning of the reversed bit_vector.
const_reverse_iterator rend() const | Reversible Container | Returns a const_reverse_iterator pointing to the end of the reversed bit_vector.
size_type size() const | Container | Returns the number of elements in the bit_vector.
size_type max_size() const | Container | Returns the largest possible size of the bit_vector.
size_type capacity() const | bit_vector | See below.
bool empty() const | Container | true if the bit_vector's size is 0.
reference operator[](size_type n) | Random Access Container | Returns the n'th element.
const_reference operator[](size_type n) const | Random Access Container | Returns the n'th element.
bit_vector() | Container | Creates an empty bit_vector.
bit_vector(size_type n) | Sequence | Creates a bit_vector with n elements.
bit_vector(size_type n, bool t) | Sequence | Creates a bit_vector with n copies of t.
bit_vector(const bit_vector&) | Container | The copy constructor.
template <class InputIterator>
bit_vector(InputIterator, InputIterator)
[1]
Sequence Creates a bit_vector with a copy of a range.
~bit_vector() | Container | The destructor.
bit_vector& operator=(const bit_vector&) | Container | The assignment operator
void reserve(size_t) | bit_vector | See below.
reference front() | Sequence | Returns the first element.
const_reference front() const | Sequence | Returns the first element.
reference back() | Back Insertion Sequence | Returns the last element.
const_reference back() const | Back Insertion Sequence | Returns the last element.
void push_back(const T&) | Back Insertion Sequence | Inserts a new element at the end.
void pop_back() | Back Insertion Sequence | Removes the last element.
void swap(bit_vector&) | Container | Swaps the contents of two bit_vectors.
void swap(bit_vector::reference x,
          bit_vector::reference y)
bit_vector See below.
iterator insert(iterator pos, bool x) | Sequence | Inserts x before pos.
template <class InputIterator>
void insert(iterator pos,
            InputIterator f, InputIterator l)
[1]
Sequence Inserts the range [f, l) before pos.
void insert(iterator pos,
            size_type n, bool x)
Sequence Inserts n copies of x before pos.
void erase(iterator pos) | Sequence | Erases the element at position pos.
void erase(iterator first, iterator last) | Sequence | Erases the range [first, last)
void clear() | Sequence | Erases all of the elements.
bool operator==(const bit_vector&,
                const bit_vector&)
Forward Container Tests two bit_vectors for equality. This is a global function, not a member function.
bool operator<(const bit_vector&,
               const bit_vector&)
Forward Container Lexicographical comparison. This is a global function, not a member function.

New members

These members are not defined in the Random access container and Back insertion sequence requirements, but are specific to vector.
Member | Description
reference | A proxy class that acts as a reference to a single bit; the reason it exists is to allow expressions like V[0] = true. (A proxy class like this is necessary, because the C++ memory model does not include independent addressing of objects smaller than one byte.) The public member functions of reference are operator bool() const, reference& operator=(bool), and void flip(). That is, reference acts like an ordinary reference: you can convert a reference to bool, assign a bool value through a reference, or flip the bit that a reference refers to.
size_type capacity() const | Number of bits for which memory has been allocated. capacity() is always greater than or equal to size(). [2] [3]
void reserve(size_type n) | If n is less than or equal to capacity(), this call has no effect. Otherwise, it is a request for the allocation of additional memory. If the request is successful, then capacity() is greater than or equal to n; otherwise, capacity() is unchanged. In either case, size() is unchanged. [2] [4]
void swap(bit_vector::reference x,
          bit_vector::reference y)
Swaps the bits referred to by x and y. This is a global function, not a member function. It is necessary because the ordinary version of swap takes arguments of type T&, and bit_vector::reference is a class, not a built-in C++ reference.

Notes

[1] This member function relies on member template functions, which at present (early 1998) are not supported by all compilers. If your compiler supports member templates, you can call this function with any type of input iterator. If your compiler does not yet support member templates, though, then the arguments must either be of type const bool* or of type bit_vector::const_iterator.

[2] Memory will be reallocated automatically if more than capacity() - size() bits are inserted into the bit_vector. Reallocation does not change size(), nor does it change the values of any bits of the bit_vector. It does, however, increase capacity(), and it invalidates [5] any iterators that point into the bit_vector.

[3] When it is necessary to increase capacity(), bit_vector usually increases it by a factor of two. It is crucial that the amount of growth is proportional to the current capacity(), rather than a fixed constant: in the former case inserting a series of bits into a bit_vector is a linear time operation, and in the latter case it is quadratic.

[4] reserve() is used to cause a reallocation manually. The main reason for using reserve() is efficiency: if you know the capacity to which your bit_vector must eventually grow, then it is probably more efficient to allocate that memory all at once rather than relying on the automatic reallocation scheme. The other reason for using reserve() is to control the invalidation of iterators. [5]

[5] A bit_vector's iterators are invalidated when its memory is reallocated. Additionally, inserting or deleting a bit in the middle of a bit_vector invalidates all iterators that point to bits following the insertion or deletion point. It follows that you can prevent a bit_vector's iterators from being invalidated if you use reserve() to preallocate as much storage as the bit_vector will ever use, and if all insertions and deletions are at the bit_vector's end.

See also

vector


Character Traits

Category: utilities | Component type: concept

Description

Several library components, including strings, need to perform operations on characters. A Character Traits class is similar to a function object: it encapsulates some information about a particular character type, and some operations on that type.

Note that every member of a Character Traits class is static. There is never any need to create a Character Traits object, and, in fact, there is no guarantee that creating such objects is possible.

Refinement of

Character Traits is not a refinement of any other concept.

Associated types

Value type | X::char_type | The character type described by this Character Traits type.
Int type | X::int_type | A type that is capable of representing every valid value of type char_type, and, additionally an end-of-file value. For char, for example, the int type may be int, and for wchar_t it may be wint_t.
Position type | X::pos_type | A type that can represent the position of a character of type char_type within a file. This type is usually streampos.
Offset type | X::off_type | An integer type that can represent the difference between two pos_type values. This type is usually streamoff.
State type | X::state_type | A type that can represent a state in a multibyte encoding scheme. This type, if used at all, is usually mbstate_t.

Notation

X | A type that is a model of Character Traits.
c, c1, c2 | A value of X's value type, X::char_type.
e, e1, e2 | A value of X's int type, X::int_type.
n | A value of type size_t.
p, p1, p2 | A non-null pointer of type const X::char_type*.
s | A non-null pointer of type X::char_type*.

Valid Expressions

Name | Expression | Type requirements | Return type
Character assignment | X::assign(c1, c2) | c1 is a modifiable lvalue. | void
Character equality | X::eq(c1, c2) |  | bool
Character comparison | X::lt(c1, c2) |  | bool
Range comparison | X::compare(p1, p2, n) |  | int
Length | X::length(p) |  | size_t
Find | X::find(p, n, c) |  | const X::char_type*
Move | X::move(s, p, n) |  | X::char_type*
Copy | X::copy(s, p, n) |  | X::char_type*
Range assignment | X::assign(s, n, c) |  | X::char_type*
EOF value | X::eof() |  | X::int_type
Not EOF | X::not_eof(e) |  | X::int_type
Convert to value type | X::to_char_type(e) |  | X::char_type
Convert to int type | X::to_int_type(c) |  | X::int_type
Equal int type values | X::eq_int_type(e1, e2) |  | bool

Expression semantics

Name | Expression | Precondition | Semantics | Postcondition
Character assignment | X::assign(c1, c2) |  | Performs the assignment c1 = c2 | X::eq(c1, c2) is true.
Character equality | X::eq(c1, c2) |  | Returns true if and only if c1 and c2 are equal. |
Character comparison | X::lt(c1, c2) |  | Returns true if and only if c1 is less than c2. Note that for any two value values c1 and c2, exactly one of X::lt(c1, c2), X::lt(c2, c1), and X::eq(c1, c2) should be true. |
Range comparison | X::compare(p1, p2, n) | [p1, p1+n) and [p2, p2+n) are valid ranges. | Generalization of strncmp. Returns 0 if every element in [p1, p1+n) is equal to the corresponding element in [p2, p2+n), a negative value if there exists an element in [p1, p1+n) less than the corresponding element in [p2, p2+n) and all previous elements are equal, and a positive value if there exists an element in [p1, p1+n) greater than the corresponding element in [p2, p2+n) and all previous elements are equal. |
Length | X::length(p) |  | Generalization of strlen. Returns the smallest non-negative number n such that X::eq(p+n, X::char_type()) is true. Behavior is undefined if no such n exists. |
Find | X::find(p, n, c) | [p, p+n) is a valid range. | Generalization of strchr. Returns the first pointer q in [p, p+n) such that X::eq(*q, c) is true. Returns a null pointer if no such pointer exists. (Note that this method for indicating a failed search differs from that is find.) |
Move | X::move(s, p, n) | [p, p+n) and [s, s+n) are valid ranges (possibly overlapping). | Generalization of memmove. Copies values from the range [p, p+n) to the range [s, s+n), and returns s. |
Copy | X::copy(s, p, n) | [p, p+n) and [s, s+n) are valid ranges which do not overlap. | Generalization of memcpy. Copies values from the range [p, p+n) to the range [s, s+n), and returns s. |
Range assignment | X::assign(s, n, c) | [s, s+n) is a valid range. | Generalization of memset. Assigns the value c to each pointer in the range [s, s+n), and returns s. |
EOF value | X::eof() |  | Returns a value that can represent EOF. | X::eof() is distinct from every valid value of type X::char_type. That is, there exists no value c such that X::eq_int_type(X::to_int_type(c), X::eof()) is true.
Not EOF | X::not_eof(e) |  | Returns e if e represents a valid char_type value, and some non-EOF value if e is X::eof(). |
Convert to value type | X::to_char_type(e) |  | Converts e to X's int type. If e is a representation of some char_type value then it returns that value; if e is X::eof() then the return value is unspecified. |
Convert to int type | X::to_int_type(c) |  | Converts c to X's int type. | X::to_char_type(X::to_int_type(c)) is a null operation.
Equal int type values | X::eq_int_type(e1, e2) |  | Compares two int type values. If there exist values of type X::char_type such that e1 is X::to_int_type(c1)) and e2 is X::to_int_type(c2)), then X::eq_int_type(e1, e2) is the same as X::eq(c1, c2). Otherwise, eq_int_type returns true if e1 and e2 are both EOF and false if one of e1 and e2 is EOF and the other is not. |

Complexity guarantees

length, find, move, copy, and the range version of assign are linear in n.

All other operations are constant time.

Models

  • char_traits<char>
  • char_traits<wchar_t>

Notes

See also

string


char_producer

Category: containers | Component type: type

Description

Char_producter<charT> is a helper class for rope. Its only purpose is for the creation of ropes that use lazy evaluation. A rope that uses lazy evaluation is one that does not store the value of the nth character until the value of that particular character is actually needed. This is sometimes a useful optimization.

Char_producer<charT> is an abstract base class; it provides an empty virtual destructor and a pure virtual operator(). Only subclasses of char_producer can be used, not char_producer directly.

Classes derived from char_producer define a method for computing the characters in a rope lazily, whenever those characters are needed. Unlike Function Objects, char_producers can be stored inside a rope data structure. All char producers must be derived from the single base class char_producer.

For performance reasons, the operator() inside char_producer is invoked to fill a buffer with a sequence of characters rather than producing a single character at a time. Its declaration is

  virtual void operator()(size_t start_pos, size_t len, charT* buffer) = 0;

An invocation of operator() requests that len characters starting at start_pos should be deposited into buffer. If the character at the nth position is requested twice, the same character must be returned both times. (That is, a char_producer must represent a specific, deterministic sequence of characters.)

The following is an example of how to use char_producer and lazy evaluation: it is a (somewhat naive implementation of a) char_producer subclass, which allows an entire file to be treated as a rope. A rope constructed from file_char_prod will contain the same character sequence as the file specified in the constructor. The file will be read only when the rope is accessed, not when the rope is constructed.

void fail(char* s) {
  fprintf(stderr, "%s errno = %d\n", s, errno);
  exit(1);
}

class file_char_prod : public char_producer<char> {
  public:
    FILE* f;
    file_char_prod(char *file_name) {
      if (NULL == (f = fopen(file_name, "rb")))
        fail("Open failed");
    }

    ~file_char_prod() { fclose(f); }

    virtual void operator()(size_t start_pos, size_t len, char* buffer) {
      if (fseek(f, start_pos, SEEK_SET)) fail("Seek failed");
      if (fread(buffer, sizeof(char), len, f) < len) fail("Read failed");
    }

    long len() {
        // Return the length of a file; this is the only
        //   mechanism that the standard C library makes possible.
      if (fseek(f, 0, SEEK_END)) fail("Seek failed");
      return ftell(f);
    }
};

The following program uses the above class to extract and write the middle 200 characters of a file. Note that even if it is invoked on a gigabyte file, it will still only read approximately 200 characters from the file. Likewise, the rope will only require a small amount of memory.

int main(int argc, char** argv)
{
  if (argc != 2)
    fail("wrong number of arguments");

  file_char_prod* fcp = new file_char_prod(argv[1]);
  crope s(fcp, fcp -> len(), true);
  size_t len = s.size();
  crope middle = s.substr(len/2 - 100, 200) + "\n";
  fwrite(middle.c_str(), sizeof(char), middle.size(), stdout);
}

Definition

Defined in rope, and in the backward-compatibility header rope.h. The char_producer class is an SGI extension; it is not part of the C++ standard.

Template parameters

Parameter | Description | Default
charT | The character type |

Model of

Assignable

Type requirements

charT is a model of Assignable.

Members

Member | Where defined | Description
virtual ~char_producer() | char_producer | A virtual destructor.
virtual void operator()(size_t start_pos,
                        size_t len,
                        charT* buffer)
Copy len characters starting at position start_pos in the string into buffer. If a character at a particular position is requested more than once, each request must result in the same character. Note that this is a pure virtual function; it must be overridden by every subclass of char_producer.

Notes

See also

rope, Function object


char_traits

Category: utilities | Component type: type

Description

The char_traits class is the default Character Traits class used by the library; it is the only predefined Character Traits class.

Example

The char_traits class is of no use by itself. It is used as a template parameter of other classes, such as the basic_string template.

Definition

Defined in the standard header string.

Template parameters

Parameter | Description | Default
charT | char_traits's value type, i.e. char_traits<>::char_type. |

Model of

Character Traits

Type requirements

charT is either char or wchar_t.

(All of char_traits's member functions are defined for arbitrary types, but some of char_traits's members must be explicitly specialized if char_traits is to be useful for other types than char and wchar_t.

Public base classes

None.

Members

All of char_traits's members are static. There is never any reason to create an object of type char_traits.
Member | Where defined | Description
char_type | Character Traits | char_traits's value type: charT.
int_type | Character Traits | char_traits's int type.
pos_type | Character Traits | char_traits's position type.
off_type | Character Traits | char_traits's offset type
state_type | Character Traits | char_traits's state type.
static void assign(char_type& c1, const char_type& c2) | Character Traits | Assigns c2 to c1.
static bool eq(const char_type& c1, const char_type& c2) | Character Traits | Character equality.
static bool lt(const char_type& c1, const char_type& c2) | Character Traits | Returns true if c1 is less than c2.
static int compare(const char_type* p1, const char_type* p2, size_t n) | Character Traits | Three-way lexicographical comparison, much like strncmp.
Length | static size_t length(const char* p) | Returns length of a null-terminated array of characters.
static const char_type* find(const char_type* p, size_t n, const char_type& c) | Character Traits | Finds c in [p, p+n), returning 0 if not found.
static char_type* move(char_type* s, const char_type* p, size_t n) | Character Traits | Copies characters from [p, p+n) to the (possibly overlapping) range [s, s+n).
static char_type* copy(char_type* s, const char_type* p, size_t n) | Character Traits | Copies characters from [p, p+n) to the (non-overlapping) range [s, s+n).
static char_type* assign(char_type* s, size_t n, char_type c) | Character Traits | Assigns the value c to every element in the range [s, s+n).
static int_type eof() | Character Traits | Returns the value used as an EOF indicator.
static int_type not_eof(const int_type& c) | Character Traits | Returns a value that is not equal to eof(). Returns c unless c is equal to eof().
static char_type to_char_type(const int_type& c) | Character Traits | Returns the char_type value corresponding to c, if such a value exists.
static int_type to_int_type(const char_type& c) | Character Traits | Returns a int_type representation of c.
static bool eq_int_type(cosnt int_type& c1, const int_type& c1) | Character Traits | Tests whether two int_type values are equal. If the values can also be represented as char_type, then eq and eq_int_type must be consistent with each other.

New members

None. All of char_traits's members are defined in the Character Traits requirements.

Notes

See also

Character Traits, string


STL Complexity Specifications

STL container, algorithm, and concept specifications include asymptotic complexity specifications. For example, iterators are required to take constant time, that is the time required by an iterator operation should be no more than a fixed constant, independent of the size of the container to which it refers.

Clearly programs will still function if a program component ignores the complexity specifications. Nonetheless, these specifications are an important part of the interface between STL components and code that uses them. If they are ignored, the performance of the resulting program will often render it useless.

As an example, consider the STL vector container. Ignoring the complexity specification, it is possible to implement vector using the same underlying data structure as list, i.e. as a doubly linked list. But for a vector of length 10,000, this would probably slow down an average computation of v[i] by something like a factor of 5,000. For a program that requires many vector accesses, such as a typical numerical computation, this is likely to change an execution time of minutes to days.

This does not preclude the use of STL algorithms in conjunction with containers or iterators that do not meet the standard complexity specifications. This is occasionally quite useful, especially if the code is either not performance critical, or other requirements on the container make the performance specifications unrealizable. But this has two potential problems. First, the algorithm may no longer be the right one, or even a reasonable one, for the problem. A different algorithm may be better tailored to actual relative costs of the container operations. Second, the algorithm is, of course, unlikely to satisfy its specified complexity constraint.

The complexity specifications in STL are, of necessity, an oversimplification. A full specification would describe exactly how the running time of an operation varies with that of the operations it invokes. The result would be rather unmanageable for the user, who would have to be keep track of large amounts of irrelevent detail. It would be overly constraining on the implementor, since overall improvements on the existing algorithms may not satisfy such detailed constraints.

Concept specifications (e.g. Forward Iterator or Container) specify complexity requirements that should be met by all instances of the concept. This is the minimum behavior required by operations (e.g. sort) parameterized with respect to the concept. Any specific instance (e.g. vector) is likely to perform better in at least some cases.

It is difficult to specify precisely when an algorithm satisfies a performance constraint. Does copying a vector on a 16-bit embedded processor take constant time? After all, the size of the vector is limited to some value less than 65,536. Thus the number of memory operations involved in the copy operation is certainly bounded by a constant. It is even conceivable that the worst case vector copy time on this processor may be less than the worst-case time for a single memory access on a machine with paged virtual memory. Nonetheless, it would be intuitively wrong to describe a vector copy or a list traversal as being a constant time operation. Even on this machine, a vector implemented as a list is unlikely to yield satisfactory performance. (Of course, so would an implementation that looped for a second for every vector access, although that would clearly run in constant time. The point here is to communicate the proper intent between implementor and user, not to guard against malicious or silly implementations.)

Fundamentally, it is difficult to define the notion of asymptotic algorithm complexity precisely for real computer hardware instead of an abstract machine model. Thus we settle for the following guidelines:

  1. For an algorithm A to have running time O(f(n)), there must be a corresponding algorithm A' that is correct on machines with arbitrarily long pointer and size_t types, such that A and A' perform essentially the same sequence of operations on the actual hardware. (In simple cases A and A' will be the same. In other cases A may have been simplified with the knowledge that adresses are bounded.) For inputs of sufficiently large size n, A' must take at most time Cf(n), where C is a constant, independent of both n and the address size. (Pointer, size_t, and ptrdiff_t operations are presumed to take constant time independent of their size.)
  2. All container or iterator complexity specifications refer to amortized complexity. An individual operation may take longer than specified. But any sufficiently long sequence of operations on the same container or iterator will take at most as long as the corresponding sum of the specified operation costs.
  3. Algorithms specify either worst-case or average case performance, and identify which. Unless otherwise stated, averages assume that container elements are chosen from a finite type with more possible values than the size of the container, and that container elements are independently uniformly distributed.
  4. A complexity specification for an operation f assumes that operations invoked by f require at most the specified runtime. But algorithms generally remain appropriate if the invoked operations are no more than a logarithmic factor slower than specified in the expected case.
  5. If operations are more expensive than assumed by a function F in the current STL, then F will slow down at most in proportion to the added cost. Any future operations that fail to satisfy this property will make that explicit.

    To make this precise, assume F is specified to use time f(m) for input of size m. F uses operations Gk, with specified running times gk(n) on input size n. If F is used in a context in which each Gk is slower than expected by at most a factor h(n), then F slows down by at most a factor h(m). This holds because none of the current algorithms ever apply the operations Gk to inputs significantly larger than m.


construct

Category: allocators | Component type: function

Prototype

template <class T1, class T2> void construct(T1* p, const T2& value);

Description

In C++, the operator new allocates memory for an object and then creates an object at that location by calling a constructor. Occasionally, however, it is useful to separate those two operations. [1] If p is a pointer to memory that has been allocated but not initialized, then construct(p, value) creates an object of type T1 at the location pointed to by p. The argument value is passed as an argument to T1's constructor.

Definition

Defined in the standard header memory, and in the nonstandard backward-compatibility header algo.h. The construct algorithm is no longer part of the C++ standard; it was present in early drafts, and it is retained in this implementation for backward compatibility.

Requirements on types

  • T1 must have a constructor that takes a single argument of type T2.

Preconditions

  • p is a valid pointer that points to a region of memory whose size is at least sizeof(T1).
  • The memory pointed to by p is uninitialized. That is, no object has been constructed at the location p.

Complexity

Example

double* dp = (double*) malloc(sizeof(double));
construct(dp, 3);
assert(*dp == 3);

Notes

[1] In particular, construct, along with other low-level memory allocation primitives, is used to implement container classes.

See also

Allocators, destroy, uninitialized_copy, uninitialized_fill, uninitialized_fill_n, raw_storage_iterator


Container

Category: containers | Component type: concept

Description

A Container is an object that stores other objects (its elements), and that has methods for accessing its elements. In particular, every type that is a model of Container has an associated iterator type that can be used to iterate through the Container's elements.

There is no guarantee that the elements of a Container are stored in any definite order; the order might, in fact, be different upon each iteration through the Container. Nor is there a guarantee that more than one iterator into a Container may be active at any one time. (Specific types of Containers, such as Forward Container, do provide such guarantees.)

A Container "owns" its elements: the lifetime of an element stored in a container cannot exceed that of the Container itself. [1]

Refinement of

Assignable

Associated types

Value type | X::value_type | The type of the object stored in a container. The value type must be Assignable, but need not be DefaultConstructible. [2]
Iterator type | X::iterator | The type of iterator used to iterate through a container's elements. The iterator's value type is expected to be the container's value type. A conversion from the iterator type to the const iterator type must exist. The iterator type must be an input iterator. [3]
Const iterator type | X::const_iterator | A type of iterator that may be used to examine, but not to modify, a container's elements. [3] [4]
Reference type | X::reference | A type that behaves as a reference to the container's value type. [5]
Const reference type | X::const_reference | A type that behaves as a const reference to the container's value type. [5]
Pointer type | X::pointer | A type that behaves as a pointer to the container's value type. [6]
Distance type | X::difference_type | A signed integral type used to represent the distance between two of the container's iterators. This type must be the same as the iterator's distance type. [2]
Size type | X::size_type | An unsigned integral type that can represent any nonnegative value of the container's distance type. [2]

Notation

X | A type that is a model of Container
a, b | Object of type X
T | The value type of X

Definitions

The size of a container is the number of elements it contains. The size is a nonnegative number.

The area of a container is the total number of bytes that it occupies. More specifically, it is the sum of the elements' areas plus whatever overhead is associated with the container itself. If a container's value type T is a simple type (as opposed to a container type), then the container's area is bounded above by a constant times the container's size times sizeof(T). That is, if a is a container with a simple value type, then a's area is O(a.size()).

A variable sized container is one that provides methods for inserting and/or removing elements; its size may vary during a container's lifetime. A fixed size container is one where the size is constant throughout the container's lifetime. In some fixed-size container types, the size is determined at compile time.

Valid expressions

In addition to the expressions defined in Assignable, EqualityComparable, and LessThanComparable, the following expressions must be valid.
Name | Expression | Type requirements | Return type
Beginning of range | a.begin() |  | iterator if a is mutable, const_iterator otherwise [4] [7]
End of range | a.end() |  | iterator if a is mutable, const_iterator otherwise [4]
Size | a.size() |  | size_type
Maximum size | a.max_size() |  | size_type
Empty container | a.empty() |  | Convertible to bool
Swap | a.swap(b) |  | void

Expression semantics

Semantics of an expression is defined only where it differs from, or is not defined in, Assignable, Equality Comparable, or LessThan Comparable
Name | Expression | Precondition | Semantics | Postcondition
Copy constructor | X(a) |  |  | X().size() == a.size(). X() contains a copy of each of a's elements.
Copy constructor | X b(a); |  |  | b.size() == a.size(). b contains a copy of each of a's elements.
Assignment operator | b = a |  |  | b.size() == a.size(). b contains a copy of each of a's elements.
Destructor | a.~X() |  | Each of a's elements is destroyed, and memory allocated for them (if any) is deallocated. |
Beginning of range | a.begin() |  | Returns an iterator pointing to the first element in the container. [7] | a.begin() is either dereferenceable or past-the-end. It is past-the-end if and only if a.size() == 0.
End of range | a.end() |  | Returns an iterator pointing one past the last element in the container. | a.end() is past-the-end.
Size | a.size() |  | Returns the size of the container, that is, its number of elements. [8] | a.size() >= 0 && a.size() <= max_size()
Maximum size | a.max_size() |  | Returns the largest size that this container can ever have. [8] | a.max_size() >= 0 && a.max_size() >= a.size()
Empty container | a.empty() |  | Equivalent to a.size() == 0. (But possibly faster.) |
Swap | a.swap(b) |  | Equivalent to swap(a,b) [9] |

Complexity guarantees

The copy constructor, the assignment operator, and the destructor are linear in the container's size.

begin() and end() are amortized constant time.

size() is linear in the container's size. [10] max_size() and empty() are amortized constant time. If you are testing whether a container is empty, you should always write c.empty() instead of c.size() == 0. The two expressions are equivalent, but the former may be much faster.

swap() is amortized constant time. [9]

Invariants

Valid range | For any container a, [a.begin(), a.end()) is a valid range. [11]
Range size | a.size() is equal to the distance from a.begin() to a.end().
Completeness | An algorithm that iterates through the range [a.begin(), a.end()) will pass through every element of a. [11]

Models

  • vector

Notes

[1] The fact that the lifetime of elements cannot exceed that of of their container may seem like a severe restriction. In fact, though, it is not. Note that pointers and iterators are objects; like any other objects, they may be stored in a container. The container, in that case, "owns" the pointers themselves, but not the objects that they point to.

[2] This expression must be a typedef, that is, a synonym for a type that already has some other name.

[3] This may either be a typedef for some other type, or else a unique type that is defined as a nested class within the class X.

[4] A container's iterator type and const iterator type may be the same: there is no guarantee that every container must have an associated mutable iterator type. For example, set and hash_set define iterator and const_iterator to be the same type.

[5] It is required that the reference type has the same semantics as an ordinary C++ reference, but it need not actually be an ordinary C++ reference. Some implementations, for example, might provide additional reference types to support non-standard memory models. Note, however, that "smart references" (user-defined reference types that provide additional functionality) are not a viable option. It is impossible for a user-defined type to have the same semantics as C++ references, because the C++ language does not support redefining the member access operator (operator.).

[6] As in the case of references [5], the pointer type must have the same semantics as C++ pointers but need not actually be a C++ pointer. "Smart pointers," however, unlike "smart references", are possible. This is because it is possible for user-defined types to define the dereference operator and the pointer member access operator, operator* and operator->.

[7] The iterator type need only be an input iterator, which provides a very weak set of guarantees; in particular, all algorithms on input iterators must be "single pass". It follows that only a single iterator into a container may be active at any one time. This restriction is removed in Forward Container.

[8] In the case of a fixed-size container, size() == max_size().

[9] For any Assignable type, swap can be defined in terms of assignment. This requires three assignments, each of which, for a container type, is linear in the container's size. In a sense, then, a.swap(b) is redundant. It exists solely for the sake of efficiency: for many containers, such as vector and list, it is possible to implement swap such that its run-time complexity is constant rather than linear. If this is possible for some container type X, then the template specialization swap(X&, X&) can simply be written in terms of X::swap(X&). The implication of this is that X::swap(X&) should only be defined if there exists such a constant-time implementation. Not every container class X need have such a member function, but if the member function exists at all then it is guaranteed to be amortized constant time.

[10] For many containers, such as vector and deque, size is O(1). This satisfies the requirement that it be O(N).

[11] Although [a.begin(), a.end()) must be a valid range, and must include every element in the container, the order in which the elements appear in that range is unspecified. If you iterate through a container twice, it is not guaranteed that the order will be the same both times. This restriction is removed in Forward Container.

See also

The Iterator overview, Input Iterator, Sequence


copy

Category: algorithms | Component type: function

Prototype

template <class InputIterator, class OutputIterator>
OutputIterator copy(InputIterator first, InputIterator last,
                    OutputIterator result);

Description

Copy copies elements from the range [first, last) to the range [result, result + (last - first)). That is, it performs the assignments *result = *first, *(result + 1) = *(first + 1), and so on. [1] Generally, for every integer n from 0 to last - first, copy performs the assignment *(result + n) = *(first + n). Assignments are performed in forward order, i.e. in order of increasing n. [2]

The return value is result + (last - first)

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

  • InputIterator is a model of Input Iterator.
  • OutputIterator is a model of Output Iterator.
  • InputIterator's value type is convertible to a type in OutputIterator's set of value types.

Preconditions

  • [first, last) is a valid range.
  • result is not an iterator within the range [first, last).
  • There is enough space to hold all of the elements being copied. More formally, the requirement is that [result, result + (last - first)) is a valid range. [1]

Complexity

Linear. Exactly last - first assignments are performed.

Example

vector<int> V(5);
iota(V.begin(), V.end(), 1);

list<int> L(V.size());
copy(V.begin(), V.end(), L.begin());
assert(equal(V.begin(), V.end(), L.begin()));

Notes

[1] Note the implications of this. Copy cannot be used to insert elements into an empty Container: it overwrites elements, rather than inserting elements. If you want to insert elements into a Sequence, you can either use its insert member function explicitly, or else you can use copy along with an insert_iterator adaptor.

[2] The order of assignments matters in the case where the input and output ranges overlap: copy may not be used if result is in the range [first, last). That is, it may not be used if the beginning of the output range overlaps with the input range, but it may be used if the end of the output range overlaps with the input range; copy_backward has opposite restrictions. If the two ranges are completely nonoverlapping, of course, then either algorithm may be used. The order of assignments also matters if result is an ostream_iterator, or some other iterator whose semantics depends on the order or assignments.

See also

copy_backward, copy_n


copy_backward

Category: algorithms | Component type: function

Prototype

template <class BidirectionalIterator1, class BidirectionalIterator2>
BidirectionalIterator2 copy_backward(BidirectionalIterator1 first,
                                     BidirectionalIterator1 last,
                                     BidirectionalIterator2 result);

Description

Copy_backward copies elements from the range [first, last) to the range [result - (last - first), result) [1]. That is, it performs the assignments *(result - 1) = *(last - 1), *(result - 2) = *(last - 2), and so on. Generally, for every integer n from 0 to last - first, copy_backward performs the assignment *(result - n - 1) = *(last - n - 1). Assignments are performed from the end of the input sequence to the beginning, i.e. in order of increasing n. [2]

The return value is result - (last - first)

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

  • BidirectionalIterator1 and BidirectionalIterator2 are models of BidirectionalIterator.
  • BidirectionalIterator1's value type is convertible to BidirectionalIterator2's value type.

Preconditions

  • [first, last) is a valid range.
  • result is not an iterator within the range [first, last).
  • There is enough space to hold all of the elements being copied. More formally, the requirement is that [result - (last - first), result) is a valid range.

Complexity

Linear. Exactly last - first assignments are performed.

Example

vector<int> V(15);
iota(V.begin(), V.end(), 1);
copy_backward(V.begin(), V.begin() + 10, V.begin() + 15);

Notes

[1] Result is an iterator that points to the end of the output range. This is highly unusual: in all other STL algorithms that denote an output range by a single iterator, that iterator points to the beginning of the range.

[2] The order of assignments matters in the case where the input and output ranges overlap: copy_backward may not be used if result is in the range [first, last). That is, it may not be used if the end of the output range overlaps with the input range, but it may be used if the beginning of the output range overlaps with the input range; copy has opposite restrictions. If the two ranges are completely nonoverlapping, of course, then either algorithm may be used.

See also

copy, copy_n


copy_n

Category: algorithms | Component type: function

Prototype

template <class InputIterator, class Size, class OutputIterator>
OutputIterator copy_n(InputIterator first, Size count,
                      OutputIterator result);

Description

Copy_n copies elements from the range [first, first + n) to the range [result, result + n). That is, it performs the assignments *result = *first, *(result + 1) = *(first + 1), and so on. Generally, for every integer i from 0 up to (but not including) n, copy_n performs the assignment *(result + i) = *(first + i). Assignments are performed in forward order, i.e. in order of increasing n. [1]

The return value is result + n.

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h. This function is an SGI extension; it is not part of the C++ standard.

Requirements on types

  • InputIterator is a model of Input Iterator.
  • OutputIterator is a model of Output Iterator.
  • Size is an integral type.
  • InputIterator's value type is convertible to a type in OutputIterator's set of value types.

Preconditions

  • n >= 0.
  • [first, first + n) is a valid range.
  • result is not an iterator within the range [first, first + n).
  • [result, result + n) is a valid range.

Complexity

Linear. Exactly n assignments are performed.

Example

vector<int> V(5);
iota(V.begin(), V.end(), 1);

list<int> L(V.size());
copy_n(V.begin(), V.size(), L.begin());
assert(equal(V.begin(), V.end(), L.begin()));

Notes

[1] Copy_n is almost, but not quite, redundant. If first is an input iterator, as opposed to a forward iterator, then the copy_n operation can't be expressed in terms of copy.

See also

copy, copy_backward


count

Category: algorithms | Component type: function

Prototype

Count is an overloaded name: there are two count functions.
template <class InputIterator, class EqualityComparable>
iterator_traits<InputIterator>::difference_type
count(InputIterator first, InputIterator last,
      const EqualityComparable& value);

template <class InputIterator, class EqualityComparable, class Size>
void count(InputIterator first, InputIterator last,
           const EqualityComparable& value,
           Size& n);

Description

Count finds the number of elements in [first, last) that are equal to value. More precisely, the first version of count returns the number of iterators i in [first, last) such that *i == value. The second version of count adds to n the number of iterators i in [first, last) such that *i == value.

The second version of count was the one defined in the original STL, and the first version is the one defined in the draft C++ standard; the definition was changed because the older interface was clumsy and error-prone. The older interface required the use of a temporary variable, which had to be initialized to 0 before the call to count.

Both interfaces are currently supported [1], for reasons of backward compatibility, but eventually the older version will be removed.

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

For the first version, which takes three arguments:
  • InputIterator is a model of Input Iterator.
  • EqualityComparable is a model of Equality Comparable.
  • InputIterator's value type is a model of Equality Comparable.
  • An object of InputIterator's value type can be compared for equality with an object of type EqualityComparable.
For the second version, which takes four arguments:
  • InputIterator is a model of Input Iterator.
  • EqualityComparable is a model of Equality Comparable.
  • Size is an integral type that can hold values of InputIterator's distance type.
  • InputIterator's value type is a model of Equality Comparable.
  • An object of InputIterator's value type can be compared for equality with an object of type EqualityComparable.

Preconditions

  • [first, last) is a valid range.
For the second version:
  • [first, last) is a valid range.
  • n plus the number of elements equal to value does not exceed the maximum value of type Size.

Complexity

Linear. Exactly last - first comparisons.

Example

int main() {
  int A[] = { 2, 0, 4, 6, 0, 3, 1, -7 };
  const int N = sizeof(A) / sizeof(int);

  cout << "Number of zeros: "
       << count(A, A + N, 0)
       << endl;
}

Notes

[1] The new count interface uses the iterator_traits class, which relies on a C++ feature known as partial specialization. Many of today's compilers don't implement the complete standard; in particular, many compilers do not support partial specialization. If your compiler does not support partial specialization, then you will not be able to use the newer version of count, or any other STL components that involve iterator_traits.

See also

count_if, find, find_if


count_if

Category: algorithms | Component type: function

Prototype

Count_if is an overloaded name: there are two count_if functions.
template <class InputIterator, class Predicate>
iterator_traits<InputIterator>::difference_type
count_if(InputIterator first, InputIterator last, Predicate pred);

template <class InputIterator, class Predicate, class Size>
void count_if(InputIterator first, InputIterator last,
              Predicate pred,
              Size& n);

Description

Count_if finds the number of elements in [first, last) that satisfy the predicate pred. More precisely, the first version of count_if returns the number of iterators i in [first, last) such that pred(*i) is true. The second version of count adds to n the number of iterators i in [first, last) such that pred(*i) is true.

The second version of count_if was the one defined in the original STL, and the first version is the one defined in the draft C++ standard; the definition was changed because the older interface was clumsy and error-prone. The older interface required the use of a temporary variable, which had to be initialized to 0 before the call to count_if.

Both interfaces are currently supported [1], for reasons of backward compatibility, but eventually the older version will be removed.

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

For the first version, which takes three arguments:
  • InputIterator is a model of Input Iterator.
  • Predicate is a model of Predicate.
  • InputIterator's value type is convertible to Predicate's argument type.
For the second version, which takes four arguments:
  • InputIterator is a model of Input Iterator.
  • Predicate is a model of Predicate.
  • Size is an integral type that can hold values of InputIterator's distance type.
  • InputIterator's value type is convertible to Predicate's argument type.

Preconditions

For the first version:
  • [first, last) is a valid range.
For the second version:
  • [first, last) is a valid range.
  • n plus the number of elements that satisfy pred does not exceed the maximum value of type Size.

Complexity

Linear. Exactly last - first applications of pred.

Example

int main() {
  int A[] = { 2, 0, 4, 6, 0, 3, 1, -7 };
  const int N = sizeof(A) / sizeof(int);

  cout << "Number of even elements: "
       << count_if(A, A + N,
                   compose1(bind2nd(equal_to<int>(), 0),
                            bind2nd(modulus<int>(), 2)))
       << endl;
}

Notes

[1] The new count interface uses the iterator_traits class, which relies on a C++ feature known as partial specialization. Many of today's compilers don't implement the complete standard; in particular, many compilers do not support partial specialization. If your compiler does not support partial specialization, then you will not be able to use the newer version of count, or any other STL components that involve iterator_traits.

See also

count, find, find_if


Default Constructible

Category: utilities | Component type: concept

Description

A type is DefaultConstructible if it has a default constructor, that is, if it is possible to construct an object of that type without initializing the object to any particular value.

Refinement of

Associated types

Notation

X | A type that is a model of DefaultConstructible
x | An object of type X

Definitions

Valid expressions

Name | Expression | Type requirements | Return type
Default constructor | X() |  | X
Default constructor | X x; [1] |  |

Expression semantics

Name | Expression | Precondition | Semantics | Postcondition
Default constructor | X() |  |  |
Default constructor | X x; |  |  |

Complexity guarantees

Models

  • int
  • vector<double>

Notes

[1] The form X x = X() is not guaranteed to be a valid expression, because it uses a copy constructor. A type that is DefaultConstructible is not necessarily Assignable

See also

Assignable


deque<T, Alloc>

Category: containers | Component type: type

Description

A deque [1] is very much like a vector: like vector, it is a sequence that supports random access to elements, constant time insertion and removal of elements at the end of the sequence, and linear time insertion and removal of elements in the middle.

The main way in which deque differs from vector is that deque also supports constant time insertion and removal of elements at the beginning of the sequence [2]. Additionally, deque does not have any member functions analogous to vector's capacity() and reserve(), and does not provide any of the guarantees on iterator validity that are associated with those member functions. [3]

Example

deque<int> Q;
Q.push_back(3);
Q.push_front(1);
Q.insert(Q.begin() + 1, 2);
Q[2] = 0;
copy(Q.begin(), Q.end(), ostream_iterator<int>(cout, " "));
// The values that are printed are 1 2 0

Definition

Defined in the standard header deque, and in the nonstandard backward-compatibility header deque.h.

Template parameters

Parameter | Description | Default
T | The deque's value type: the type of object that is stored in the deque. |
Alloc | The deque's allocator, used for all internal memory management. | alloc

Model of

Random access container, Front insertion sequence, Back insertion sequence.

Type requirements

None, except for those imposed by the requirements of Random access container, Front insertion sequence, and Back insertion sequence.

Public base classes

None.

Members

Member | Where defined | Description
value_type | Container | The type of object, T, stored in the deque.
pointer | Container | Pointer to T.
reference | Container | Reference to T
const_reference | Container | Const reference to T
size_type | Container | An unsigned integral type.
difference_type | Container | A signed integral type.
iterator | Container | Iterator used to iterate through a deque.
const_iterator | Container | Const iterator used to iterate through a deque.
reverse_iterator | Reversible Container | Iterator used to iterate backwards through a deque.
const_reverse_iterator | Reversible Container | Const iterator used to iterate backwards through a deque.
iterator begin() | Container | Returns an iterator pointing to the beginning of the deque.
iterator end() | Container | Returns an iterator pointing to the end of the deque.
const_iterator begin() const | Container | Returns a const_iterator pointing to the beginning of the deque.
const_iterator end() const | Container | Returns a const_iterator pointing to the end of the deque.
reverse_iterator rbegin() | Reversible Container | Returns a reverse_iterator pointing to the beginning of the reversed deque.
reverse_iterator rend() | Reversible Container | Returns a reverse_iterator pointing to the end of the reversed deque.
const_reverse_iterator rbegin() const | Reversible Container | Returns a const_reverse_iterator pointing to the beginning of the reversed deque.
const_reverse_iterator rend() const | Reversible Container | Returns a const_reverse_iterator pointing to the end of the reversed deque.
size_type size() const | Container | Returns the size of the deque.
size_type max_size() const | Container | Returns the largest possible size of the deque.
bool empty() const | Container | true if the deque's size is 0.
reference operator[](size_type n) | Random Access Container | Returns the n'th element.
const_reference operator[](size_type n) const | Random Access Container | Returns the n'th element.
deque() | Container | Creates an empty deque.
deque(size_type n) | Sequence | Creates a deque with n elements.
deque(size_type n, const T& t) | Sequence | Creates a deque with n copies of t.
deque(const deque&) | Container | The copy constructor.
template <class InputIterator>
deque(InputIterator f, InputIterator l)
[4]
Sequence Creates a deque with a copy of a range.
~deque() | Container | The destructor.
deque& operator=(const deque&) | Container | The assignment operator
reference front() | Front Insertion Sequence | Returns the first element.
const_reference front() const | Front Insertion Sequence | Returns the first element.
reference back() | Back Insertion Sequence | Returns the last element.
const_reference back() const | Back Insertion Sequence | Returns the last element.
void push_front(const T&) | Front Insertion Sequence | Inserts a new element at the beginning.
void push_back(const T&) | Back Insertion Sequence | Inserts a new element at the end.
void pop_front() | Front Insertion Sequence | Removes the first element.
void pop_back() | Back Insertion Sequence | Removes the last element.
void swap(deque&) | Container | Swaps the contents of two deques.
iterator insert(iterator pos,
                const T& x)
Sequence Inserts x before pos.
template <class InputIterator>
void insert(iterator pos,
            InputIterator f, InputIterator l)
[4]
Sequence Inserts the range [f, l) before pos.
void insert(iterator pos,
            size_type n, const T& x)
Sequence Inserts n copies of x before pos.
iterator erase(iterator pos) | Sequence | Erases the element at position pos.
iterator erase(iterator first, iterator last) | Sequence | Erases the range [first, last)
void clear() | Sequence | Erases all of the elements.
void resize(n, t = T()) | Sequence | Inserts or erases elements at the end such that the size becomes n.
bool operator==(const deque&,
                const deque&)
Forward Container Tests two deques for equality. This is a global function, not a member function.
bool operator<(const deque&,
               const deque&)
Forward Container Lexicographical comparison. This is a global function, not a member function.

New members

All of deque's members are defined in the Random access container, Front insertion sequence, and Back insertion sequence requirements. Deque does not introduce any new members.

Notes

[1] The name deque is pronounced "deck", and stands for "double-ended queue." Knuth (section 2.6) reports that the name was coined by E. J. Schweppe. See section 2.2.1 of Knuth for more information about deques. (D. E. Knuth, The Art of Computer Programming. Volume 1: Fundamental Algorithms, second edition. Addison-Wesley, 1973.)

[2] Inserting an element at the beginning or end of a deque takes amortized constant time. Inserting an element in the middle is linear in n, where n is the smaller of the number of elements from the insertion point to the beginning, and the number of elements from the insertion point to the end.

[3] The semantics of iterator invalidation for deque is as follows. Insert (including push_front and push_back) invalidates all iterators that refer to a deque. Erase in the middle of a deque invalidates all iterators that refer to the deque. Erase at the beginning or end of a deque (including pop_front and pop_back) invalidates an iterator only if it points to the erased element.

[4] This member function relies on member template functions, which at present (early 1998) are not supported by all compilers. If your compiler supports member templates, you can call this function with any type of input iterator. If your compiler does not yet support member templates, though, then the arguments must either be of type const value_type* or of type deque::const_iterator.

See also

vector, list, slist


STL Design Documents

  • Thread safety
  • The meaning of complexity specifications
  • Representations of strings
  • Rope Implementation Overview
  • SGI STL Allocator Design


destroy

Category: allocators | Component type: function

Prototype

Destroy is an overloaded name; there are actually two destroy functions.
template <class T> void destroy(T* pointer);

template <class ForwardIterator>
void destroy(ForwardIterator first, ForwardIterator last);

Description

In C++, the operator delete destroys an object by calling its destructor, and then deallocates the memory where that object was stored. Occasionally, however, it is useful to separate those two operations. [1] Destroy calls an object's destructor without deallocating the memory where the object was stored.

The first version of destroy destroys the object pointed to by pointer by calling the destructor T::~T(). The memory pointed to by pointer is not deallocated, and can be reused for some other object.

The second version of destroy destroys all of the objects in the range of elements [first, last). It is equivalent to calling destroy(&*i) for each iterator i in the range [first, last).

Definition

Defined in the standard header memory, and in the nonstandard backward-compatibility header algo.h. The destroy algorithms are no longer part of the C++ standard; they were present in early drafts, and they are retained in this implementation for backward compatibility.

Requirements on types

For the first version of destroy:
  • T's destructor, ~T, is accessible.
For the second version of destroy:
  • ForwardIterator is a model of Forward Iterator.
  • ForwardIterator is mutable.
  • ForwardIterator's value type has an accessible destructor.

Preconditions

For the first version of destroy:
  • pointer points to a valid object of type T.
For the second version of destroy:
  • [first, last) is a valid range.
  • Each iterator i in [first, last) points to a valid object.

Complexity

The run-time complexity of the second version is linear: it calls the destructor exactly last - first times.

Example

class Int {
public:
  Int(int x) : val(x) {}
  int get() { return val; }
private:
  int val;
};

int main()
{
  Int A[] = { Int(1), Int(2), Int(3), Int(4) };

  destroy(A, A + 4);
  construct(A,     Int(10));
  construct(A + 1, Int(11));
  construct(A + 2, Int(12));
  construct(A + 3,  Int(13));
}

Notes

[1] In particular, destroy, along with other low-level memory allocation primitives, is used to implement container classes.

See also

Allocators, construct, uninitialized_copy, uninitialized_fill, uninitialized_fill_n, raw_storage_iterator


distance

Categories: algorithms, iterators | Component type: function

Prototype

Distance is an overloaded name; there are actually two distance functions.
template <class InputIterator>
inline iterator_traits<InputIterator>::difference_type
distance(InputIterator first, InputIterator last);

template <class InputIterator, class Distance>
void distance(InputIterator first, InputIterator last, Distance& n);

Description

Finds the distance between first and last, i.e. the number of times that first must be incremented until it is equal to last. [1] The first version of distance, which takes two arguments, simply returns that distance; the second version, which takes three arguments and which has a return type of void, increments n by that distance.

The second version of distance was the one defined in the original STL, and the first version is the one defined in the draft C++ standard; the definition was changed because the older interface was clumsy and error-prone. The older interface required the use of a temporary variable, and it has semantics that are somewhat nonintuitive: it increments n by the distance from first to last, rather than storing that distance in n. [2]

Both interfaces are currently supported [3], for reasons of backward compatibility, but eventually the older version will be removed.

Definition

Defined in the standard header iterator, and in the nonstandard backward-compatibility header iterator.h.

Requirements on types

For the first version:
  • InputIterator is a model of Input Iterator.
For the second version:
  • InputIterator is a model of Input Iterator.
  • Distance is an integral type that is able to represent a distance between iterators of type InputIterator.

Preconditions

  • [first, last) is a valid range, as defined in the Input Iterator requirements.

Complexity

Constant time if InputIterator is a model of random access iterator, otherwise linear time.

Example

int main() {
  list<int> L;
  L.push_back(0);
  L.push_back(1);

  assert(distance(L.begin(), L.end()) == L.size());
}

Notes

[1] This is the reason that distance is not defined for output iterators: it is impossible to compare two output iterators for equality.

[2] Forgetting to initialize n to 0 is a common mistake.

[3] The new distance interface uses the iterator_traits class, which relies on a C++ feature known as partial specialization. Many of today's compilers don't implement the complete standard; in particular, many compilers do not support partial specialization. If your compiler does not support partial specialization, then you will not be able to use the newer version of distance, or any other STL components that involve iterator_traits.

See also

distance_type, advance, Input iterator, Random access iterator, Iterator tags, iterator_traits, Iterator overview.


distance_type

Category: iterators | Component type: function

Prototype

Distance_type is overloaded; it is in fact five different functions.
template <class T, class Distance>
inline Distance* distance_type(const input_iterator<T, Distance>&);

template <class T, class Distance>
inline Distance* distance_type(const forward_iterator<T, Distance>&);

template <class T, class Distance>
inline Distance* distance_type(const bidirectional_iterator<T, Distance>&);

template <class T, class Distance>
inline Distance* distance_type(const random_access_iterator<T, Distance>&);

template <class T> inline ptrdiff_t* distance_type(const T*);

Description

Distance_type is an iterator tag function: it is used to determine the distance type associated with an iterator. An Input Iterator, Forward Iterator, Bidirectional Iterator, or Random Access Iterator [1] must have associated with it some signed integral type that is used to represent the distance between two iterators of that type. In some cases (such as an algorithm that must declare a local variable that represents the size of a range), it is necessary to find out an iterator's distance type. Accordingly, distance_type(Iter) returns (Distance*) 0, where Distance is Iter's distance type.

Although distance_type looks like a single function whose return type depends on its argument type, in reality it is a set of functions; the name distance_type is overloaded. The function distance_type must be overloaded for every iterator type [1].

In practice, ensuring that distance_type is defined requires essentially no work at all. It is already defined for pointers, and for the base classes input_iterator, forward_iterator, bidirectional_iterator, and random_access_iterator. If you are implementing a new type of forward iterator, for example, you can simply derive it from the base class forward_iterator; this means that distance_type (along with iterator_category and value_type) will automatically be defined for your iterator. These base classes are empty: they contain no member functions or member variables, but only type information. Using them should therefore incur no overhead.

Note that, while the function distance_type was present in the original STL, it is no longer present in the most recent draft C++ standard: it has been replaced by the iterator_traits class. At present both mechanisms are supported [2], but eventually distance_type will be removed.

Definition

Defined in the standard header iterator, and in the nonstandard backward-compatibility header iterator.h. This function is no longer part of the C++ standard, although it was present in early drafts of the standard. It is retained in this implementation for backward compatibility.

Requirements on types

The argument of distance_type must be an Input Iterator, Forward Iterator, Bidirectional Iterator, or Random Access Iterator. [1]

Preconditions

None. Distance_type's argument is even permitted to be a singular iterator.

Complexity

At most amortized constant time. In many cases, a compiler should be able to optimize away distance_type entirely.

Example

template <class RandomAccessIterator, class LessThanComparable,
          class Distance>
RandomAccessIterator __lower_bound(RandomAccessIterator first,
                                   RandomAccessIterator last,
                                   const LessThanComparable& value,
                                   Distance*)
    Distance len = last - first;
    Distance half;
    RandomAccessIterator middle;

    while (len > 0) {
        half = len / 2;
        middle = first + half;
        if (*middle < value) {
            first = middle + 1;
            len = len - half - 1;
        } else
            len = half;
    }
    return first;
}

template <class RandomAccessIterator, class LessThanComparable>
inline RandomAccessIterator lower_bound(RandomAccessIterator first,
                                        RandomAccessIterator last,
                                        const LessThanComparable& value) {
    return __lower_bound(first, last, value, distance_type(first));
}
The algorithm lower_bound (a type of binary search) takes a range of iterators, and must declare a local variable whose type is the iterators' distance type. It uses distance type, and an auxiliary function, so that it can declare that variable. [3] Note: this is a simplified example. The actual algorithm lower_bound can operate on a range of Random Access Iterators or a range of Forward Iterators. It uses both distance_type and iterator_category.

Notes

[1] Note that distance_type is not defined for Output Iterators or for Trivial Iterators. There is no meaningful definition of a distance for either of those concepts, so there is no need for a distance type.

[2] The iterator_traits class relies on a C++ feature known as partial specialization. Many of today's compilers don't implement the complete standard; in particular, many compilers do not support partial specialization. If your compiler does not support partial specialization, then you will not be able to use iterator_traits, and you will have to continue using the functions iterator_category, distance_type, and value_type. This is one reason that those functions have not yet been removed.

[3] This use of an auxiliary function is an extremely common idiom: distance_type is almost always used with auxiliary functions, simply because it returns type information in a form that is hard to use in any other way. This is one of the reasons that distance_type is so much less convenient than iterator_traits.

See also

The Iterator Tags overview, iterator_traits, iterator_category, value_type, output_iterator_tag, input_iterator_tag, forward_iterator_tag, bidirectional_iterator_tag, random_access_iterator_tag


divides<T>

Category: functors | Component type: type

Description

Divides<T> is a function object. Specifically, it is an Adaptable Binary Function. If f is an object of class divides<T> and x and y are objects of class T, then f(x,y) returns x/y.

Example

Each element in V3 will be the quotient of the corresponding elements in V1 and V2
const int N = 1000;
vector<double> V1(N);
vector<double> V2(N);
vector<double> V3(N);

iota(V1.begin(), V1.end(), 1);
fill(V2.begin(), V2.end(), 75);

assert(V2.size() >= V1.size() && V3.size() >= V1.size());
transform(V1.begin(), V1.end(), V2.begin(), V3.begin(),
          divides<double>());

Definition

Defined in the standard header functional, and in the nonstandard backward-compatibility header function.h.

Template parameters

Parameter | Description | Default
T | The function object's argument type and result type. |

Model of

Adaptable Binary Function, Default Constructible

Type requirements

T must be a numeric type; if x and y are objects of type T, then x/y must be defined and must have a return type that is convertible to T. T must be Assignable.

Public base classes

binary_function<T, T, T>

Members

Member | Where defined | Description
first_argument_type | Adaptable Binary Function | The type of the first argument: T
second_argument_type | Adaptable Binary Function | The type of the second argument: T
result_type | Adaptable Binary Function | The type of the result: T
T operator()(const T& x, const T& y) | Adaptable Binary Function | Function call operator. The return value is x / y.
divides() | Default Constructible | The default constructor.

New members

All of divides's members are defined in the Adaptable Binary Function and Default Constructible requirements. Divides does not introduce any new members.

Notes

See also

The Function Object overview, Adaptable Binary Function, binary_function, plus, minus, multiplies, modulus, negate


How to use the STL documentation

This site documents all of the components (classes, functions, and concepts) in the SGI Standard Template Library. Each page describes a single component, and also includes links to related components.

This documentation assumes a general familiarity with C++, especially with C++ templates. Additionally, you should read Introduction to the Standard Template Library before proceeding to the pages that describe individual components: the introductory page defines several terms that are used throughout the documentation.

Classification of STL components

The STL components are divided into six broad categories on the basis of functionality: Containers, Iterators, Algorithms, Function Objects, Utilities, and Allocators; these categories are defined in the Introduction, and the Table of Contents is organized according to them.

The STL documentation contains two indices. One of them, the Main Index, lists all components in alphabetical order. The other, the Divided Index, contains a separate alphabetical listing for each category. The Divided Index includes one category that is not present in the Table of Contents: Adaptors. An adaptor is a class or a function that transforms one interface into a different one. The reason that adaptors don't appear in the Table of Contents is that no component is merely an adaptor, but always an adaptor and something else; stack, for example, is a container and an adaptor. Accordingly, stack appears in two different places in the Divided Index. There are several other components that appear in the Divided Index in more than one place.

The STL documentation classifies components in two ways.

  1. Categories are a classification by functionality. The categories are:
    • Container
    • Iterator
    • Algorithm
    • Function Object
    • Utility
    • Adaptor
    • Allocator.
  2. Component types are a structural classification: one based on what kind of C++ entity (if any) a component is. The component types are:
    • Type (i.e. a struct or class)
    • Function
    • Concept (as defined in the Introduction).

These two classification schemes are independent, and each of them applies to every STL component; vector, for example, is a type whose category is Containers, and Forward Iterator is a concept whose category is Iterators.

Both of these classification schemes appear at the top of every page that documents an STL component. The upper left corner identifies the the component's category as Containers, Iterators, Algorithms, Function Objects, Utilities, Adaptors, or Allocators, and the upper right corner identifies the component as a type, a function, or a concept.

Using the STL documentation

The STL is a generic library: almost every class and function is a template. Accordingly, one of the most important purposes of the STL documentation is to provide a clear description of which types may be used to instantiate those templates. As described in the Introduction, a concept is a generic set of requirements that a type must satisfy: a type is said to be a model of a concept if it satisfies all of that concept's requirements.

Concepts are used very heavily in the STL documentation, both because they directly express type requirements, and because they are a tool for organizing types conceptually. (For example, the fact that ostream_iterator and insert_iterator are both models of Output Iterator is an important statement about what those two classes have in common.) Concepts are used for the documentation of both types and functions.

The format of a concept page

A page that documents a concept has the following sections.

  • Summary: A description of the concept's purpose.
  • Refinement of: A list of other concepts that this concept refines, with links to those concepts.
  • Associated types: A concept is a set of requirements on some type. Frequently, however, some of those requirements involve some other type. For example, one of the Unary Function requirements is that a Unary Function must have an argument type; if F is a type that models Unary Function and f is an object of type F, then, in the expression f(x), x must be of F's argument type. If a concept does have any such associated types, then they are defined in this section.
  • Notation: The next three sections, definitions, valid expressions, and expression semantics, present expressions involving types that model the concept being defined. This section defines the meaning of the variables and identifiers used in those expressions.
  • Definitions: Some concepts, such as LessThan Comparable, use specialized terminology. If a concept requires any such terminology, it is defined in this section.
  • Valid Expressions: A type that models a concept is required to support certain operations. In most cases, it doesn't make sense to describe this in terms of specific functions or member functions: it doesn't make any difference, for example, whether a type that models Input Iterator uses a global function or a member function to provide operator++. This section lists the expressions that a type modeling this concept must support. It includes any special requirements (if any) on the types of the expression's operands, and the expression's return type (if any).
  • Expression Semantics: The previous section, valid expressions, lists which expressions involving a type must be supported; it doesn't, however, define the meaning of those expressions. This section does: it lists the semantics, preconditions, and postconditions for the expressions defined in the previous section.
  • Complexity Guarantees: In some cases, the run-time complexity of certain operations is an important part of a concept's requirements. For example, one of the most significant distinctions between a Bidirectional Iterator and a Random Access Iterator is that, for random access iterators, expressions like p + n take constant time. Any such requirements on run-time complexity are listed in this section.
  • Invariants: Many concepts require that some property is always true for objects of a type that models the concept being defined. For example, LessThan Comparable imposes the requirement of transitivity: if x < y and y < z, then x < z. Some such properties are "axioms" (that is, they are independent of any other requirements) and some are "theorems" (that is, they follow either from requirements in the expression semantics section or from other requirements in the invariants section).
  • Models: A list of examples of types that are models of this concept. Note that this list is not intended to be complete: in most cases a complete list would be impossible, because there are an infinite number of types that could model the concept.
  • Notes: Footnotes (if any) that are referred to by other parts of the page.
  • See Also: Links to other related pages.

The format of a type page

A page that documents a type has the following sections.

  • Description. A summary of the type's properties.
  • Example of use: A code fragment involving the type.
  • Definition: A link to the source code where the type is defined.
  • Template parameters: Almost all STL structs and classes are templates. This section lists the name of each template parameter, its purpose, and its default value (if any).
  • Model of: A list of the concepts that this type is a model of, and links to those concepts. Note that a type may be a model of more than one concept: vector, for example, is a model of both Random Access Container and Back Insertion Sequence. If a type is a model of two different concepts, that simply means that it satisfies the requirements of both.
  • Type requirements: The template parameters of a class template usually must satisfy a set of requirements. Many of these can simply be expressed by listing which concept a template parameter must conform to, but some type requirements are slightly more complicated, and involve a relationship between two different template parameters.
  • Public base classes: If this class inherits from any other classes, they are listed in this section.
  • Members: A list of this type's nested types, member functions, member variables, and associated non-member functions. In most cases these members are simply listed, rather than defined: since the type is a model of some concept, detailed definitions aren't usually necessary. For example, vector is a model of Container, so the description of the member function begin() in the Container page applies to vector, and there is no need to repeat it in the vector page. Instead, the Members section provides a very brief description of each member and a link to whatever page defines that member more fully.
  • New Members: A type might have some members that are not part of the requirements of any of the concepts that it models. For example, vector has a member function called capacity(), which is not part of the Random Access Container or Back Insertion Sequence requirements. These members are defined in the New members section.
  • Notes: Footnotes (if any) that are referred to by other parts of the page.
  • See Also: Links to other related pages.

The format of a function page

A page that documents a function has the following sections.

  • Prototype: the function's declaration.
  • Description: A summary of what the function does.
  • Definition: A link to the source code where the function is defined.
  • Requirements on types: Most functions in the STL are function templates. This section lists the requirements that must be satisfied by the function's template parameters. Sometimes the requirements can simply be expressed by listing which concept a template parameter must conform to, but sometimes they are more complicated and involve a relationship between two different template parameters. In the case of find, for example, the requirements are that the parameter InputIterator is a model of Input Iterator, that the parameter EqualityComparable is a model of Equality Comparable, and that comparison for equality is possible between objects of type EqualityComparable and objects of InputIterator's value types.
  • Preconditions: Functions usually aren't guaranteed to yield a well-defined result for any possible input, but only for valid input; it is an error to call a function with invalid input. This section describes the conditions for validity.
  • Complexity: Guarantees on the function's run-time complexity. For example, find's run-time complexity is linear in the length of the input range.
  • Example of use: A code fragment that illustrates how to use the function.
  • Notes: Footnotes (if any) that are referred to by other parts of the page.
  • See Also: Links to other related pages.


Dr. Dobb's Journal Interview with Alex Stepanov

Al Stevens Interviews Alex Stepanov

This interview appeared in the March 1995 issue of Dr. Dobb's Journal, and is reprinted with permission.

Tell us something about your long-term interest in generic programming.

I started thinking about generic programming in the late 70s when I observed that some algorithms depended not on some particular implementation of a data structure but only on a few fundamental semantic properties of the structure. I started going through many different algorithms, and I found that most algorithms can be abstracted away from a particular implementation in such a way that efficiency is not lost. Efficiency is a fundamental concern of mine. It is silly to abstract an algorithm in such a way that when you instantiate it back it becomes inefficient.

At that time I thought that the right way of doing this kind of research was to develop a programming language, which is what I started doing with two of my friends, Deepak Kapur, who at present is a professor at State University of New York, Albany, and David Musser, professor at Rensselaer Polytechnic Institute. At that time the three of us worked at the General Electric Research Center at Schenectady, NY. We started working on a language called Tecton, which would allow people to describe algorithms associated with what we called generic structures, which is just a collection of formal types and properties of these types. Sort of mathematical stuff. We realized that one can define an algebra of operations on these structures, you can refine them, you can enrich them, and do all sorts of things.

There were some interesting ideas, but the research didn't lead to practical results because Tecton was functional. We believed Backus's idea that we should liberate programming from the von Neumann style, and we didn't want to have side effects. That limited our ability to handle very many algorithms that require the notion of state and side effects.

The interesting thing about Tecton, which I realized sometime in the late 70s, was that there was a fundamental limitation in the accepted notion of an abstract data type. People usually viewed abstract data types as something which tells you only about the behavior of an object and the implementation is totally hidden. It was commonly assumed that the complexity of an operation is part of implementation and that abstraction ignores complexity. One of the things that is central to generic programming as I understand it now, is that complexity, or at least some general notion of complexity, has to be associated with an operation.

Let's take an example. Consider an abstract data type stack. It's not enough to have Push and Pop connected with the axiom wherein you push something onto the stack and after you pop the stack you get the same thing back. It is of paramount importance that pushing the stack is a constant time operation regardless of the size of the stack. If I implement the stack so that every time I push it becomes slower and slower, no one will want to use this stack.

We need to separate the implementation from the interface but not at the cost of totally ignoring complexity. Complexity has to be and is a part of the unwritten contract between the module and its user. The reason for introducing the notion of abstract data types was to allow interchangeable software modules. You cannot have interchangeable modules unless these modules share similar complexity behavior. If I replace one module with another module with the same functional behavior but with different complexity tradeoffs, the user of this code will be unpleasantly surprised. I could tell him anything I like about data abstraction, and he still would not want to use the code. Complexity assertions have to be part of the interface.

Around 1983 I moved from GE Research to the faculty of the Polytechnic University, formerly known as Brooklyn Polytechnic, in NY. I started working on graph algorithms. My principal collaborator was Aaron Kershenbaum, now at IBM Yorktown Heights. He was an expert in graph and network algorithms, and I convinced him that some of the ideas of high order and generic programming were applicable to graph algorithms. He had some grants and provided me with support to start working with him to apply these ideas to real network algorithms. He was interested in building a toolbox of high order generic components so that some of these algorithms could be implemented, because some of the network algorithms are so complex that while they are theoretically analyzed, but never implemented. I decided to use a dialect of Lisp called Scheme to build such a toolbox. Aaron and I developed a large library of components in Scheme demonstrating all kinds of programming techniques. Network algorithms were the primary target. Later Dave Musser, who was still at GE Research, joined us, and we developed even more components, a fairly large library. The library was used at the university by graduate students, but was never used commercially. I realized during this activity that side effects are important, because you cannot really do graph operations without side effects. You cannot replicate a graph every time you want to modify a vertex. Therefore, the insight at that time was that you can combine high order techniques when building generic algorithms with disciplined use of side effects. Side effects are not necessarily bad; they are bad only when they are misused.

In the summer of 1985 I was invited back to GE Research to teach a course on high order programming. I demonstrated how you can construct complex algorithms using this technique. One of the people who attended was Art Chen, then the manager of the Information Systems Laboratory. He was sufficiently impressed to ask me if I could produce an industrial strength library using these techniques in Ada, provided that I would get support. Being a poor assistant professor, I said yes, even though I didn't know any Ada at the time. I collaborated with Dave Musser in building this Ada library. It was an important undertaking, because switching from a dynamically typed language, such as Scheme, to a strongly typed language, such as Ada, allowed me to realize the importance of strong typing. Everybody realizes that strong typing helps in catching errors. I discovered that strong typing, in the context of Ada generics, was also an instrument of capturing designs. It was not just a tool to catch bugs. It was also a tool to think. That work led to the idea of orthogonal decomposition of a component space. I realized that software components belong to different categories. Object-oriented programming aficionados think that everything is an object. When I was working on the Ada generic library, I realized that this wasn't so. There are things that are objects. Things that have state and change their state are objects. And then there are things that are not objects. A binary search is not an object. It is an algorithm. Moreover, I realized that by decomposing the component space into several orthogonal dimensions, we can reduce the number of components, and, more importantly, we can provide a conceptual framework of how to design things.

Then I was offered a job at Bell Laboratories working in the C++ group on C++ libraries. They asked me whether I could do it in C++. Of course, I didn't know C++ and, of course, I said I could. But I couldn't do it in C++, because in 1987 C++ didn't have templates, which are essential for enabling this style of programming. Inheritance was the only mechanism to obtain genericity and it was not sufficient.

Even now C++ inheritance is not of much use for generic programming. Let's discuss why. Many people have attempted to use inheritance to implement data structures and container classes. As we know now, there were few if any successful attempts. C++ inheritance, and the programming style associated with it are dramatically limited. It is impossible to implement a design which includes as trivial a thing as equality using it. If you start with a base class X at the root of your hierarchy and define a virtual equality operator on this class which takes an argument of the type X, then derive class Y from class X. What is the interface of the equality? It has equality which compares Y with X. Using animals as an example (OO people love animals), define mammal and derive giraffe from mammal. Then define a member function mate, where animal mates with animal and returns an animal. Then you derive giraffe from animal and, of course, it has a function mate where giraffe mates with animal and returns an animal. It's definitely not what you want. While mating may not be very important for C++ programmers, equality is. I do not know a single algorithm where equality of some kind is not used.

You need templates to deal with such problems. You can have template class animal which has member function mate which takes animal and returns animal. When you instantiate giraffe, mate will do the right thing. The template is a more powerful mechanism in that respect.

However, I was able to build a rather large library of algorithms, which later became part of the Unix System Laboratory Standard Component Library. I learned a lot at Bell Labs by talking to people like Andy Koenig and Bjarne Stroustrup about programming. I realized that C/C++ is an important programming language with some fundamental paradigms that cannot be ignored. In particular I learned that pointers are very good. I don't mean dangling pointers. I don't mean pointers to the stack. But I mean that the general notion of pointer is a powerful tool. The notion of address is universally used. It is incorrectly believed that pointers make our thinking sequential. That is not so. Without some kind of address we cannot describe any parallel algorithm. If you attempt to describe an addition of n numbers in parallel, you cannot do it unless you can talk about the first number being added to the second number, while the third number is added to the fourth number. You need some kind of indexing. You need some kind of address to describe any kind of algorithm, sequential or parallel. The notion of an address or a location is fundamental in our conceptualizing computational processes---algorithms.

Let's consider now why C is a great language. It is commonly believed that C is a hack which was successful because Unix was written in it. I disagree. Over a long period of time computer architectures evolved, not because of some clever people figuring how to evolve architectures---as a matter of fact, clever people were pushing tagged architectures during that period of time---but because of the demands of different programmers to solve real problems. Computers that were able to deal just with numbers evolved into computers with byte-addressable memory, flat address spaces, and pointers. This was a natural evolution reflecting the growing set of problems that people were solving. C, reflecting the genius of Dennis Ritchie, provided a minimal model of the computer that had evolved over 30 years. C was not a quick hack. As computers evolved to handle all kinds of problems, C, being the minimal model of such a computer, became a very powerful language to solve all kinds of problems in different domains very effectively. This is the secret of C's portability: it is the best representation of an abstract computer that we have. Of course, the abstraction is done over the set of real computers, not some imaginary computational devices. Moreover, people could understand the machine model behind C. It is much easier for an average engineer to understand the machine model behind C than the machine model behind Ada or even Scheme. C succeeded because it was doing the right thing, not because of AT&T promoting it or Unix being written with it.

C++ is successful because instead of trying to come up with some machine model invented by just contemplating one's navel, Bjarne started with C and tried to evolve C further, allowing more general programming techniques but within the framework of this machine model. The machine model of C is very simple. You have the memory where things reside. You have pointers to the consecutive elements of the memory. It's very easy to understand. C++ keeps this model, but makes things that reside in the memory more extensive than in the C machine, because C has a limited set of data types. It has structures that allow a sort of an extensible type system, but it does not allow you to define operations on structures. This limits the extensibility of the type system. C++ moved C's machine model much further toward a truly extensible type system.

In 1988 I moved to HP Labs where I was hired to work on generic libraries. For several years, instead of doing that I worked on disk drives, which was exciting but was totally orthogonal to this area of research. I returned to generic library development in 1992 when Bill Worley, who was my lab director established an algorithms project with me being its manager. C++ had templates by then. I discovered that Bjarne had done a marvelous job at designing templates. I had participated in several discussions early on at Bell Labs about designing templates and argued rather violently with Bjarne that he should make C++ templates as close to Ada generics as possible. I think that I argued so violently that he decided against that. I realized the importance of having template functions in C++ and not just template classes, as some people believed. I thought, however, that template functions should work like Ada generics, that is, that they should be explicitly instantiated. Bjarne did not listen to me and he designed a template function mechanism where templates are instantiated implicitly using an overloading mechanism. This particular technique became crucial for my work because I discovered that it allowed me to do many things that were not possible in Ada. I view this particular design by Bjarne as a marvelous piece of work and I'm very happy that he didn't follow my advice.

When did you first conceive of the STL and what was its original purpose?

In 1992, when the project was formed, there were eight people in it. Gradually the group diminished, eventually becoming two people, me and Meng Lee. While Meng was new to the area---she was doing compilers for most of her professional life---she accepted the overall vision of generic programming research, and believed that it could lead to changing software development at the point when very few people shared this belief. I do not think that I would be able to build STL without her help. (After all, STL stands for Stepanov and Lee...) We wrote a huge library, a lot of code with a lot of data structures and algorithms, function objects, adaptors, and so on. There was a lot of code, but no documentation. Our work was viewed as a research project with the goal of demonstrating that you can have algorithms defined as generically as possible and still extremely efficient. We spent a lot of time taking measurements, and we found that we can make these algorithms as generic as they can be, and still be as efficient as hand-written code. There is no performance penalty for this style of programming! The library was growing, but it wasn't clear where it was heading as a project. It took several fortunate events to lead it toward STL.

When and why did you decide to propose STL as part of the ANSI/ISO Standard C++ definition?

During the summer of 1993, Andy Koenig came to teach a C++ course at Stanford. I showed him some of our stuff, and I think he was genuinely excited about it. He arranged an invitation for me to give a talk at the November meeting of the ANSI/ISO C++ Standards Committee in San Jose. I gave a talk entitled "The Science of C++ Programming." The talk was rather theoretical. The main point was that there are fundamental laws connecting basic operations on elements of C++ which have to be obeyed. I showed a set of laws that connect very primitive operations such as constructors, assignment, and equality. C++ as a language does not impose any constraints. You can define your equality operator to do multiplication. But equality should be equality, and it should be a reflexive operation. A should be equal to A. It should be symmetric. If A is equal to B, then B should be equal to A. And it should be transitive. Standard mathematical axioms. Equality is essential for other operations. There are axioms that connect constructors and equality. If you construct an object with a copy constructor out of another object, the two objects should be equal. C++ does not mandate this, but this is one of the fundamental laws that we must obey. Assignment has to create equal objects. So I presented a bunch of axioms that connected these basic operations. I talked a little bit about axioms of iterators and showed some of the generic algorithms working on iterators. It was a two-hour talk and, I thought, rather dry. However, it was very well received. I didn't think at that time about using this thing as a part of the standard because it was commonly perceived that this was some kind of advanced programming technique which would not be used in the "real world". I thought there was no interest at all in any of this work by practical people.

I gave this talk in November, and I didn't think about ANSI at all until January. On January 6 I got a mail message from Andy Koenig, who is the project editor of the standard document, saying that if I wanted to make my library a part of the standard, I should submit a proposal by January 25. My answer was, "Andy, are you crazy?" to which he answered, "Well, yes I am crazy, but why not try it?"

At that point there was a lot of code but there was no documentation, much less a formal proposal. Meng and I spent 80-hour weeks to come up with a proposal in time for the mailing deadline. During that time the only person who knew it was coming was Andy. He was the only supporter and he did help a lot during this period. We sent the proposal out, and waited. While doing the proposal we defined a lot of things. When you write things down, especially when you propose them as a standard, you discover all kinds of flaws with your design. We had to re-implement every single piece of code in the library, several hundred components, between the January mailing and the next meeting in March in San Diego. Then we had to revise the proposal, because while writing the code, we discovered many flaws.

Can you characterize the discussions and debate in the committee following the proposal? Was there immediate support? Opposition?

We did not believe that anything would come out of it. I gave a talk, which was very well received. There were a lot of objections, most of which took this form: this is a huge proposal, it's way too late, a resolution had been passed at the previous meeting not to accept any major proposals, and here is this enormous thing, the largest proposal ever, with a lot of totally new things. The vote was taken, and, interestingly enough, an overwhelming majority voted to review the proposal at the next meeting and put it to a vote at the next meeting in Waterloo, Ontario.

Bjarne Stroustrup became a strong supporter of STL. A lot of people helped with suggestions, modifications, and revisions. Bjarne came here for a week to work with us. Andy helped constantly. C++ is a complex language, so it is not always clear what a given construct means. Almost daily I called Andy or Bjarne to ask whether such-and-such was doable in C++. I should give Andy special credit. He conceived of STL as part of the standard library. Bjarne became the main pusher of STL on the committee. There were other people who were helpful: Mike Vilot, the head of the library group, Nathan Myers of Rogue Wave, Larry Podmolik of Andersen Consulting. There were many others.

The STL as we proposed it in San Diego was written in present C++. We were asked to rewrite it using the new ANSI/ISO language features, some of which are not implemented. There was an enormous demand on Bjarne's and Andy's time trying to verify that we were using these non-implemented features correctly.

People wanted containers independent of the memory model, which was somewhat excessive because the language doesn't include memory models. People wanted the library to provide some mechanism for abstracting memory models. Earlier versions of STL assumed that the size of the container is expressible as an integer of type size_t and that the distance between two iterators is of type ptrdiff_t. And now we were told, why don't you abstract from that? It's a tall order because the language does not abstract from that; C and C++ arrays are not parameterized by these types. We invented a mechanism called "allocator," which encapsulates information about the memory model. That caused grave consequences for every component in the library. You might wonder what memory models have to do with algorithms or the container interfaces. If you cannot use things like size_t, you also cannot use things like T* because of different pointer types (T*, T huge *, etc.). Then you cannot use references because with different memory models you have different reference types. There were tremendous ramifications on the library.

The second major thing was to extend our original set of data structures with associative data structures. That was easier, but coming up with a standard is always hard because we needed something which people would use for years to come for their containers. STL has from the point of view of containers, a very clean dichotomy. It provides two fundamental kinds of container classes: sequences and associative containers. They are like regular memory and content-addressable memory. It has a clean semantics explaining what these containers do.

When I arrived at Waterloo, Bjarne spent a lot of time explaining to me that I shouldn't be concerned, that most likely it was going to fail, but that we did our best, we tried, and we should be brave. The level of expectation was low. We expected major opposition. There was some opposition but it was minor. When the vote was taken in Waterloo, it was totally surprising because it was maybe 80% in favor and 20% against. Everybody expected a battle, everybody expected controversy. There was a battle, but the vote was overwhelming.

What effect does STL have on the class libraries published in the ANSI/ISO February 1994 working paper?

STL was incorporated into the working paper in Waterloo. The STL document is split apart, and put in different places of the library parts of the working paper. Mile Vilot is responsible for doing that. I do not take active part in the editorial activities. I am not a member of the committee but every time an STL-related change is proposed, it is run by me. The committee is very considerate.

Several template changes have been accepted by the committee. Which ones have impact on STL?

Prior to the acceptance of STL there were two changes that were used by the revised STL. One is the ability to have template member functions. STL uses them extensively to allow you to construct any kind of a container from any other kind of a container. There is a single constructor that allows you to construct vectors out of lists or out of other containers. There is a templatized constructor which is templatized on the iterator, so if you give a pair of iterators to a container constructor, the container is constructed out of the elements which are specified by this range. A range is a set of elements specified by a pair of iterators, generalized pointers, or addresses. The second significant new feature used in STL was template arguments which are templates themselves, and that's how allocators, as originally proposed, were done.

Did the requirements of STL influence any of the proposed template changes?

In Valley Forge, Bjarne proposed a significant addition to templates called "partial specialization," which would allow many of the algorithms and classes to be much more efficient and which would address a problem of code size. I worked with Bjarne on the proposal and it was driven by the need of making STL even more efficient. Let me explain what partial specialization is. At present you can have a template function parameterized by class T called swap(T&, T&) and swaps them. This is the most generic possible swap. If you want to specialize swap and do something different for a particular type, you can have a function swap(int&, int&), and which does integer swapping in some different way. However it was not possible to have an intermediate partial specialization, that is, to provide a template function of the following form:

  template <class T> void swap(vector<T>&, vector<T>&);
This form provides a special way to swap vectors. This is an important problem from an efficiency point of view. If you swap vectors with the most generic swap, which uses three assignments, vectors are copied three times, which takes linear time. However, if we have this partial specialization of swap for vectors that swap two vectors, then you can have a fast, constant time operation, that moves a couple of pointers in the vector headers. That would allow sort, for example, to work on vectors of vectors much faster. With the present STL, without partial specialization, the only way to make it work faster is for any particular kind of vector, such as vector<int>, to define its own swap, which can be done but which puts a burden on the programmer. In very many cases, partial specialization would allow algorithms to be more effective on some generic classes. You can have the most generic swap, a less generic swap, an even less generic swap, and a totally specific swap. You can do partial specialization, and the compiler will find the closest match. Another example is copy. At present the copy algorithm just goes through a sequence of elements defined by iterators and copies them one by one. However, with partial specialization we can define a template function:
  template <class T> T ** copy(T**,T**,T**);
This will efficiently copy a range of pointers by using memcpy, because when we're copying pointers we don't have to worry about construction and destruction and we can just move bits with memcpy. That can be done once and for all in the library and the user doesn't need to be concerned. We can have particular specializations of algorithms for some of the types. That was a very important change, and as far as I know it was favorably received in Valley Forge and will be part of the Standard.

What kinds of applications beyond the standard class libraries are best served by STL ?

I have hopes that STL will introduce a style of programming called generic programming. I believe that this style is applicable to any kind of application, that is, trying to write algorithms and data structures in the most generic way. Specifying families or categories of such structures satisfying common semantic requirements is a universal paradigm applicable to anything. It will take a long time before the technology is understood and developed. STL is a starting point for this type of programming.

Eventually we will have standard catalogs of generic components with well-defined interfaces, with well-defined complexities. Programmers will stop programming at the micro level. You will never need to write a binary search routine again. Even now, STL provides several binary search algorithms written in the most generic way. Anything that is binary-searchable can be searched by those algorithms. The minimum requirements that the algorithm assumes are the only requirements that the code uses. I hope that the same thing will happen for all software components. We will have standard catalogs and people will stop writing these things.

That was Doug McIlroy's dream when he published a famous paper talking about component factories in 1969. STL is an example of the programming technology which will enable such component factories. Of course, a major effort is needed, not just research effort, but industrial effort to provide programmers with such catalogs, to have tools which will allow people to find the components they need, and to glue the components together, and to verify that their complexity assumptions are met.

STL does not implement a persistent object container model. The map and multimap containers are particularly good candidates for persistent storage containers as inverted indexes into persistent object databases. Have you done any work in that direction or can you comment an such implementations?

This point was noticed by many people. STL does not implement persistence for a good reason. STL is as large as was conceivable at that time. I don't think that any larger set of components would have passed through the standards committee. But persistence is something that several people thought about. During the design of STL and especially during the design of the allocator component, Bjarne observed that allocators, which encapsulate memory models, could be used to encapsulate a persistent memory model. The insight was Bjarne's, and it is an important and interesting insight. Several object database companies are looking at that. In October 1994 I attended a meeting of the Object Database Management Group. I gave a talk on STL, and there was strong interest there to make the containers within their emerging interface to conform to STL. They were not looking at the allocators as such. Some of the members of the Group are, however, investigating whether allocators can be used to implement persistency. I expect that there will be persistent object stores with STL-conforming interfaces fitting into the STL framework within the next year.

Set, multiset, map, and multimap are implemented with a red-black tree data structure. Have you experimented with other structures such as B*trees?

I don't think that would be quite right for in-memory data structures, but this is something that needs to be done. The same interfaces defined by STL need to be implemented with other data structures---skip lists, splay trees, half-balanced trees, and so on. It's a major research activity that needs to be done because STL provides us with a framework where we can compare the performance of these structures. The interface is fixed. The basic complexity requirements are fixed. Now we can have meaningful experiments comparing different data structures to each other. There were a lot of people from the data structure community coming up with all kinds of data structures for that kind of interface. I hope that they would implement them as generic data structures within the STL framework.

Are compiler vendors working with you to implement STL into their products?

Yes. I get a lot of calls from compiler vendors. Pete Becker of Borland was extremely helpful. He helped by writing some code so that we could implement allocators for all the memory models of Borland compilers. Symantec is going to release an STL implementation for their Macintosh compiler. Edison Design Group has been very helpful. We have had a lot of support from most compiler vendors.

STL includes templates that support memory models of 16-bit MS-DOS compilers. With the current emphasis on 32-bit, flat model compilers and operating systems, do you think that the memory-model orientation will continue to be valid?

Irrespective of Intel architecture, memory model is an object, which encapsulates the information about what is a pointer, what are the integer size and difference types associated with this pointer, what is the reference type associated with this pointer, and so on. Abstracting that is important if we introduce other kinds of memory such as persistent memory, shared memory, and so on. A nice feature of STL is that the only place that mentions the machine-related types in STL---something that refers to real pointer, real reference---is encapsulated within roughly 16 lines of code. Everything else, all the containers, all the algorithms, are built abstractly without mentioning anything which relates to the machine. From the point of view of portability, all the machine-specific things which relate to the notion of address, pointer, and so on, are encapsulated within a tiny, well-understood mechanism. Allocators, however, are not essential to STL, not as essential as the decomposition of fundamental data structures and algorithms.

The ANSI/ISO C Standards committee treated platform-specific issues such as memory models as implementation details and did not attempt to codify them. Will the C++ committee be taking a different view of these issues? If so, why?

I think that STL is ahead of the C++ standard from the point of view of memory models. But there is a significant difference between C and C++. C++ has constructors and operator new, which deal with memory model and which are part of the language. It might be important now to look at generalizing things like operator new to be able to take allocators the way STL containers take allocators. It is not as important now as it was before STL was accepted, because STL data structures will eliminate the majority of the needs for using new. Most people should not allocate arrays because STL does an effective job in doing so. I never need to use new in my code, and I pay great attention to efficiency. The code tends to be more efficient than if I were to use new. With the acceptance of STL, new will sort of fade away. STL also solves the problem of deleting because, for example, in the case of a vector, the destructor will destroy it on the exit from the block. You don't need to worry about releasing the storage as you do when you use new. STL can dramatically minimize the demand for garbage collection. Disciplined use of containers allows you to do whatever you need to do without automatic memory management. The STL constructors and destructors do allocation properly.

The C++ Standard Library subcommittee is defining standard namespaces and conventions for exception handling. Will STL classes have namespaces and throw exceptions?

Yes they will. Members of the committee are dealing with that, and they are doing a great job.

How different from the current STL definition will the eventual standard definition be? Will the committee influence changes or is the design under tighter control?

It seems to be a consensus that there should not be any major changes to STL.

How can programmers gain an early experience with STL in anticipation of it becoming a standard?

They can download the STL header files from butler.hpl.hp.com under /stl and use it with Borland or IBM compiler, or with any other compiler powerful enough to handle STL The only way to learn some style of programming is by programming. They need to look at examples and write programs in this style.

You are collaborating with P.J. (Bill) Plauger to write a book about STL. What will be the emphasis of the book and when is it scheduled to be published?

It is scheduled to be published in the summer of 1995 and is going to be an annotated STL implementation. It will be similar to Bill's books on the Standard C Library and the Draft Standard C++ Library. He is taking the lead on the book, which will serve as a standard reference document on the use of the STL. I hope to write a paper with Bjarne that will address language/library interactions in the context of C++/STL. It might lead to another book.

A lot more work needs to be done. For STL to become a success, people should do research experimenting with this style of programming. More books and articles need to be written explaining how to program in this style. Courses need to be developed. Tutorials need to be written. Tools need to be built which help people navigate through libraries. STL is a framework and it would be nice to have a tool with which to browse through this framework.

What is the relationship between generic programming and object-oriented programming?

In one sense, generic programming is a natural continuation of the fundamental ideas of object-oriented programming---separating the interface and implementation and polymorphic behavior of the components. However, there is a radical difference. Object-oriented programming emphasizes the syntax of linguistic elements of the program construction. You have to use inheritance, you have to use classes, you have to use objects, objects send messages. Generic programming does not start with the notion of whether you use inheritance or you don't use inheritance. It starts with an attempt to classify or produce a taxonomy of what kinds of things are there and how they behave. That is, what does it mean that two things are equal? What is the right way to define equality? Not just actions of equality. You can analyze equality deeper and discover that there is a generic notion of equality wherein two objects are equal if their parts, or at least their essential parts are equal. We can have a generic recipe for an equality operation. We can discuss what kinds of objects there are. There are sequences. There are operations on sequences. What are the semantics of these operations? What types of sequences from the point of view of complexity tradeoffs should we offer the user? What kinds of algorithms are there on sequences? What kind of different sorting functions do we need? And only after we develop that, after we have the conceptual taxonomy of the components, do we address the issue of how to implement them. Do we use templates? Do we use inheritance? Do we use macros? What kind of language technology do we use? The fundamental idea of generic programming is to classify abstract software components and their behavior and come up with a standard taxonomy. The starting point is with real, efficient algorithms and data structures and not with the language. Of course, it is always embodied in the language. You cannot have generic programming outside of a language. STL is done in C++. You could implement it in Ada. You could implement it in other languages. They would be slightly different, but there are some fundamental things that would be there. Binary search has to be everywhere. Sort has to be everywhere. That's what people do. There will be some modification on the semantics of the containers, slight modifications imposed by the language. In some languages you can use inheritance more, in some languages you have to use templates. But the fundamental difference is precisely that generic programming starts with semantics and semantic decomposition. For example, we decide that we need a component called swap. Then we figure out how this particular component will work in different languages. The emphasis is on the semantics and semantic classification, while object-orientedness, especially as it has evolved, places a much stronger emphasis, and, I think, too much of an emphasis, on precisely how to develop things, that is, using class hierarchies. OOP tells you how to build class hierarchies, but it doesn't tell you what should be inside those class hierarchies.

What do you see as the future of STL and generic programming?

I mentioned before the dream of programmers having standard repositories of abstract components with interfaces that are well understood and that conform to common paradigms. To do that there needs to be a lot more effort to develop the scientific underpinnings of this style of programming. STL starts it to some degree by classifying the semantics of some fundamental components. We need to work more on that. The goal is to transform software engineering from a craft to an engineering discipline. It needs a taxonomy of fundamental concepts and some laws that govern those concepts, which are well understood, which can be taught, which every programmer knows even if he cannot state them correctly. Many people know arithmetic even if they never heard of commutativity. Everybody who graduated from high school knows that 2+5 is equal to 5+2. Not all of them know that it is a commutative property of addition. I hope that most programmers will learn the fundamental semantic properties of fundamental operations. What does assignment mean? What does equality mean? How to construct data structures.

At present C++ is the best vehicle for this style of programming. I have tried different languages and I think that C++ allows this marvelous combination of abstractness and efficiency. However, I think that it is possible to design a language based on C and on many of the insights that C++ brought into the world, a language which is more suitable to this style of programming, which lacks some of the deficiencies of C++, in particular its enormous size. STL deals with things called concepts. What is an iterator? Not a class. Not a type. It is a concept. (Or, if we want to be more formal, it is what Bourbaki calls a structure type, what logicians call a theory, or what type theory people call a sort.) It is something which doesn't have a linguistic incarnation in C++. But it could. You could have a language where you could talk about concepts, refine them, and then finally form them in a very programmatic kind of way into classes. (There are, of course, languages that deal with sorts, but they are not of much use if you want to sort.) We could have a language where we could define something called forward iterator, which is just defined as a concept in STL---it doesn't have a C++ incarnation. Then we can refine forward iterator into bidirectional iterator. Then random iterator can be refined from that. It is possible to design a language which would enable even far greater ease for this style of programming. I am fully convinced that it has to be as efficient and as close to the machine as are C and C++. And I do believe that it is possible to construct a language that allows close approximation to the machine on the one hand and has the ability to deal with very abstract entities on the other hand. I think that abstractness can be even greater than it is in C++ without creating a gap between underlying machines. I think that generic programming can influence language research and that we will have practical languages, which are easy to use and are well suited for that style of programming. From that you can deduce what I am planning to work on next.

Copyright © 1995 Dr. Dobb's Journal
[Silicon Surf] [STL Home]
Copyright © 1996 Silicon Graphics, Inc. All Rights Reserved. TrademarkInformation


equal

Category: algorithms | Component type: function

Prototype

Equal is an overloaded name; there are actually two equal functions.
template <class InputIterator1, class InputIterator2>
bool equal(InputIterator1 first1, InputIterator1 last1,
           InputIterator2 first2);

template <class InputIterator1, class InputIterator2,
          class BinaryPredicate>
bool equal(InputIterator1 first1, InputIterator1 last1,
           InputIterator2 first2, BinaryPredicate binary_pred);

Description

Equal returns true if the two ranges [first1, last1) and [first2, first2 + (last1 - first1)) are identical when compared element-by-element, and otherwise returns false. [1]

The first version of equal returns true if and only if for every iterator i in [first1, last1), *i == *(first2 + (i - first1)). The second version of equal returns true if and only if for every iterator i in [first1, last1), binary_pred(*i, *(first2 + (i - first1)) is true.

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

For the first version:
  • InputIterator1 is a model of Input Iterator.
  • InputIterator2 is a model of Input Iterator.
  • InputIterator1's value type is a model of Equality Comparable.
  • InputIterator2's value type is a model of Equality Comparable.
  • InputIterator1's value type can be compared for equality with InputIterator2's value type.
For the second version:
  • InputIterator1 is a model of Input Iterator.
  • InputIterator2 is a model of Input Iterator.
  • BinaryPredicate is a model of Binary Predicate.
  • InputIterator1's value type is convertible to BinaryPredicate's first argument type.
  • InputIterator2's value type is convertible to BinaryPredicate's second argument type.

Preconditions

  • [first1, last1) is a valid range.
  • [first2, first2 + (last2 - last1)) is a valid range.

Complexity

Linear. At most last1 - first1 comparisons.

Example

int A1[] = { 3, 1, 4, 1, 5, 9, 3 };
int A2[] = { 3, 1, 4, 2, 8, 5, 7 };
const int N = sizeof(A1) / sizeof(int);

cout << "Result of comparison: " << equal(A1, A1 + N, A2) << endl;

Notes

[1] Note that this is very similar to the behavior of mismatch: The only real difference is that while equal will simply return false if the two ranges differ, mismatch returns the first location where they do differ. The expression equal(f1, l1, f2) is precisely equivalent to the expression mismatch(f1, l1, f2).first == l1, and this is in fact how equal could be implemented.

See also

mismatch, search, find, find_if


Equality Comparable

Category: utilities | Component type: concept

Description

A type is EqualityComparable if objects of that type can be compared for equality using operator==, and if operator== is an equivalence relation.

Refinement of

Associated types

Notation

X | A type that is a model of EqualityComparable
x, y, z | Object of type X

Definitions

Valid expressions

Name | Expression | Type requirements | Return type
Equality | x == y |  | Convertible to bool
Inequality | x != y |  | Convertible to bool

Expression semantics

Name | Expression | Precondition | Semantics | Postcondition
Equality | x == y | x and y are in the domain of == |  |
Inequality | x != y | x and y are in the domain of == | Equivalent to !(x == y) |

Complexity guarantees

Invariants

Identity | &x == &y implies x == y
Reflexivity | x == x
Symmetry | x == y implies y == x
Transitivity | x == y and y == z implies x == z

Models

  • int
  • vector<int>

Notes

See also

LessThanComparable.


equal_range

Category: algorithms | Component type: function

Prototype

Equal_range is an overloaded name; there are actually two equal_range functions.
template <class ForwardIterator, class LessThanComparable>
pair<ForwardIterator, ForwardIterator>
equal_range(ForwardIterator first, ForwardIterator last,
            const LessThanComparable& value);

template <class ForwardIterator, class T, class StrictWeakOrdering>
pair<ForwardIterator, ForwardIterator>
equal_range(ForwardIterator first, ForwardIterator last, const T& value,
            StrictWeakOrdering comp);

Description

Equal_range is a version of binary search: it attempts to find the element value in an ordered range [first, last) [1]. The value returned by equal_range is essentially a combination of the values returned by lower_bound and upper_bound: it returns a pair of iterators i and j such that i is the first position where value could be inserted without violating the ordering and j is the last position where value could be inserted without violating the ordering. It follows that every element in the range [i, j) is equivalent to [1] value, and that [i, j) is the largest subrange of [first, last) that has this property. The first version of equal_range uses operator< for comparison, and the second uses the function object comp.

The first version of equal_range returns a pair of iterators [i, j). i is the furthermost iterator in [first, last) such that, for every iterator k in [first, i), *k < value. j is the furthermost iterator in [first, last) such that, for every iterator k in [first, j), value < *k is false. For every iterator k in [i, j), neither value < *k nor *k < value is true. [2]

The second version of equal_range returns a pair of iterators [i, j). i is the furthermost iterator in [first, last) such that, for every iterator k in [first, i), comp(*k, value) is true. j is the furthermost iterator in [first, last) such that, for every iterator k in [first, j), comp(value, *k) is false. For every iterator k in [i, j), neither comp(value, *k) nor comp(*k, value) is true. [2]

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

For the first version:
  • ForwardIterator is a model of Forward Iterator.
  • LessThanComparable is a model of LessThan Comparable.
  • The ordering on objects of type LessThanComparable is a strict weak ordering, as defined in the LessThan Comparable requirements.
  • ForwardIterator's value type is the same type as LessThanComparable.
For the second version:
  • ForwardIterator is a model of Forward Iterator.
  • StrictWeakOrdering is a model of Strict Weak Ordering.
  • ForwardIterator's value type is the same type as T.
  • ForwardIterator's value type is convertible to StrictWeakOrdering's argument type.

Preconditions

For the first version:
  • [first, last) is a valid range.
  • [first, last) is ordered in ascending order according to operator<. That is, for every pair of iterators i and j in [first, last) such that i precedes j, *j < *i is false.
For the second version:
  • [first, last) is a valid range.
  • [first, last) is ordered in ascending order according to the function object comp. That is, for every pair of iterators i and j in [first, last) such that i precedes j, comp(*j, *i) is false.

Complexity

The number of comparisons is logarithmic: at most 2 * log(last - first) + 1. If ForwardIterator is a Random Access Iterator then the number of steps through the range is also logarithmic; otherwise, the number of steps is proportional to last - first. [3]

Example

int main()
{
  int A[] = { 1, 2, 3, 3, 3, 5, 8 };
  const int N = sizeof(A) / sizeof(int);

  for (int i = 2; i <= 4; ++i) {
    pair<int*, int*> result = equal_range(A, A + N, i);

    cout << endl;
    cout << "Searching for " << i << endl;
    cout << "  First position where " << i << " could be inserted: "
         << result.first - A << endl;
    cout << "  Last position where " << i << " could be inserted: "
         << result.second - A << endl;
    if (result.first < A + N)
      cout << "  *result.first = " << *result.first << endl;
    if (result.second < A + N)
      cout << "  *result.second = " << *result.second << endl;
  }
}
The output is:
Searching for 2
  First position where 2 could be inserted: 1
  Last position where 2 could be inserted: 2
  *result.first = 2
  *result.second = 3

Searching for 3
  First position where 3 could be inserted: 2
  Last position where 3 could be inserted: 5
  *result.first = 3
  *result.second = 5

Searching for 4
  First position where 4 could be inserted: 5
  Last position where 4 could be inserted: 5
  *result.first = 5
  *result.second = 5

Notes

[1] Note that you may use an ordering that is a strict weak ordering but not a total ordering; that is, there might be values x and y such that x < y, x > y, and x == y are all false. (See the LessThan Comparable requirements for a more complete discussion.) Finding value in the range [first, last), then, doesn't mean finding an element that is equal to value but rather one that is equivalent to value: one that is neither greater than nor less than value. If you're using a total ordering, however (if you're using strcmp, for example, or if you're using ordinary arithmetic comparison on integers), then you can ignore this technical distinction: for a total ordering, equality and equivalence are the same.

[2] Note that equal_range may return an empty range; that is, it may return a pair both of whose elements are the same iterator. Equal_range returns an empty range if and only if the range [first, last) contains no elements equivalent to value. In this case it follows that there is only one position where value could be inserted without violating the range's ordering, so the return value is a pair both of whose elements are iterators that point to that position.

[3] This difference between Random Access Iterators and Forward Iterators is simply because advance is constant time for Random Access Iterators and linear time for Forward Iterators.

See also

lower_bound, upper_bound, binary_search


equal_to<T>

Category: functors | Component type: type

Description

Equal_to<T> is a function object. Specifically, it is an Adaptable Binary Predicate, which means it is a function object that tests the truth or falsehood of some condition. If f is an object of class equal_to<T> and x and y are objects of class T, then f(x,y) returns true if x == y and false otherwise.

Example

Rearrange a vector such that all of the elements that are equal to zero precede all nonzero elements.
vector<int> V;
...
partition(V.begin(), V.end(), bind2nd(equal_to<int>(), 0));

Definition

Defined in the standard header functional, and in the nonstandard backward-compatibility header function.h.

Template parameters

Parameter | Description | Default
T | The type of equal_to's arguments. |

Model of

Adaptable Binary Predicate, DefaultConstructible

Type requirements

T is EqualityComparable.

Public base classes

binary_function<T, T, bool>.

Members

Member | Where defined | Description
first_argument_type | Adaptable Binary Predicate | The type of the first argument: T
second_argument_type | Adaptable Binary Predicate | The type of the second argument: T
result_type | Adaptable Binary Predicate | The type of the result: bool
equal_to() | DefaultConstructible | The default constructor.
bool operator()(const T& x, const T& y) | Binary Function | Function call operator. The return value is x == y.

New members

All of equal_to's members are defined in the Adaptable Binary Predicate and DefaultConstructible requirements. Equal_to does not introduce any new members.

Notes

See also

The function object overview, Adaptable Binary Predicate, not_equal_to, greater, less, greater_equal, less_equal


SGI STL: Frequently Asked Questions

 SGI

Frequently Asked Questions

about the SGI Standard Template Library

Is the STL Y2K compliant?
Yes. The STL does not store or manipulate dates in any way, so there are no year 2000 issues.

Can I download this entire site for offline viewing?
Yes. From the home page, go to the Download the STL page. You will find links for downloading the entire STL documentation as a single zip, tar, or tar.gz file.

The documentation is a collection of HTML files. It does not exist in the form of a single text or PostScriptTM document. The Other Resources page lists several books about the STL.

Which compilers are supported?
The STL has been tested on these compilers: SGI 7.1 and later, or 7.0 with the -n32 or -64 flag; gcc 2.8 or egcs 1.x; Microsoft 5.0 and later. (But see below.) Boris Fomitchev distributes a port for some other compilers.

If you succeed in using the SGI STL with some other compiler, please let us know, and please tell us what modifications (if any) you had to make. We expect that most of the changes will be restricted to the <stl_config.h> header.

What about older SGI compilers?
Given the rate of improvement in C++ implementations, SGI strongly recommends that you upgrade your compiler. If this is not possible, you might try the version of the STL for older Borland and Microsoft compilers (see the Download the STL page), or Boris Fomitchev's port. Neither of these is supported.

How do I install the SGI STL?
You should unpack the STL include files in a new directory, and then use the -I (or /I) option to direct the compiler to look there first. We don't recommend overwriting the vendor's include files.

At present the SGI STL consists entirely of header files. You don't have to build or link in any additional runtime libraries.

Are there any compatibility issues with Visual C++?
Visual C++ provides its own STL implementation, and some of the other Microsoft C++ library headers may rely on that implementation. In particular, the SGI STL has not been tested in combination with Microsoft's new <iostream> header. It has been used successfully with the older <iostream.h> header.

Is the SGI STL thread safe?
Yes. However, you should be aware that not everyone uses the phrase "thread safe" the same way. See our discussion of thread safety for our design goals.

Are hash tables part of the C++ standard?
No. The hash table classes (hash_set, hash_map hash_multiset hash_multimap hash) are an extension. They may be added to a future revision of the C++ standard.

The rope and slist classes are also extensions.

Why is list<>::size() linear time?
The size() member function, for list and slist, takes time proportional to the number of elements in the list. This was a deliberate tradeoff. The only way to get a constant-time size() for linked lists would be to maintain an extra member variable containing the list's size. This would require taking extra time to update that variable (it would make splice() a linear time operation, for example), and it would also make the list larger. Many list algorithms don't require that extra word (algorithms that do require it might do better with vectors than with lists), and, when it is necessary to maintain an explicit size count, it's something that users can do themselves.

This choice is permitted by the C++ standard. The standard says that size() "should" be constant time, and "should" does not mean the same thing as "shall". This is the officially recommended ISO wording for saying that an implementation is supposed to do something unless there is a good reason not to.

One implication of linear time size(): you should never write

  if (L.size() == 0)
    ...
Instead, you should write
  if (L.empty())
    ...

Why doesn't map's operator< use the map's comparison function?
A map has a notion of comparison, since one of its template parameters is a comparison function. However, operator< for maps uses the elements' operator< rather than that comparison function. This appears odd, but it is deliberate and we believe that it is correct.

At the most trivial level, this isn't a bug in our implementation because it's what's mandated by the C++ standard. (The behavior of operator< is described in Table 65, in section 23.1.)

A more interesting question: is the requirement in the standard correct, or is there actually a bug in the standard?

We believe that the requirements in the standard are correct.

First, there's a consistency argument: operator< for a vector (or deque, or list) uses the element's operator<. Should map's operator< do something else, just because there is another plausible way to compare objects? It's reasonable to say, for all containers, that operator< always means operator<, and that if you need a different kind of comparison you can explicitly use lexicographical_compare.

Second, if we did use the map's comparison function, there would be a problem: which one do we use? There are two map arguments, and, while we know that their comparison functions have the same type, we don't know that they have the same behavior. The comparison function, after all, is a function object, and it might have internal state that affects the comparison. (You might have a function object to compare strings, for example, with a boolean flag that determines whether the comparison is case-sensitive.)

There's also a related question, incidentally: how should operator== behave for sets? A set's comparison function induces an equivalence relation, so, just as you can use the set's comparison function for lexicographical ordering, you could also use it for a version of equality. Again, though, we define operator==(const set&, const set&) so that it just calls the elements' operator==.

Why does a vector expand its storage by a factor of two when it performs a reallocation?
Expanding a vector by a factor of two is a time-space tradeoff; it means that each element will (on average) be copied twice when you're building a vector one element at a time, and that the ratio of wasted to used space is at most 1. (In general, if the exponent for expansion is r, the worst case wasted/used ratio is r - 1 and the number of times an element is copied approaches r/(r - 1). If r = 1.25, for example, then elements are copied five times instead of twice.)

If you need to control vector's memory usage more finely, you can use the member functions capacity() and reserve() instead of relying on automatic reallocation.

Why do the pop member functions return void?
All of the STL's pop member functions (pop_back in vector, list, and deque; pop_front in list, slist, and deque; pop in stack, queue, and priority_queue) return void, rather than returning the element that was removed. This is for the sake of efficiency.

If the pop member functions were to return the element that was removed then they would have to return it by value rather than by reference. (The element is being removed, so there wouldn't be anything for a reference to point to.) Return by value, however, would be inefficient; it would involve at least one unnecessary copy constructor invocation. The pop member functions return nothing because it is impossible for them to return a value in a way that is both correct and efficient.

If you need to retrieve the value and then remove it, you can perform the two operations explicitly. For example:

  std::stack<T> s;
  ...
  T old_value = s.top();
  s.pop();

How do I sort a range in descending order instead of ascending?

sort(first, last, greater<T>());
(Note that it must be greater, not greater_eq. The comparison function f must be one such that f(x, x) is false for every x.)

Why am I getting uninitialized memory reads from PurifyTM?
We believe that the uninitialized memory read (UMR) messages in STL data structures are artifacts and can be ignored.

There are a number of reasons the compiler might generate reads from uninitialized memory (e.g. structure padding, inheritance from empty base classes, which still have nonzero size). Purify tries to deal with this by distinguishing between uninitialized memory reads (UMR) and uninitialized memory copies (UMC). The latter are not displayed by default. The distinction between the two isn't completely clear, but appears to be somewhat heuristic. The validity of the heuristic seems to depend on compiler optimizations, etc. As a result, some perfectly legitimate code generates UMR messages. It's unfortunately often hard to tell whether a UMR message represents a genuine problem or just an artifact.

Why does Bounds CheckerTM say that I have memory leaks?
This is not an STL bug. It is an artifact of certain kinds of leak detectors.

In the default STL allocator, memory allocated for blocks of small objects is not returned to malloc. It can only be reused by subsequent allocate requests of (approximately) the same size. Thus programs that use the default may appear to leak memory when monitored by certain kinds of simple leak detectors. This is intentional. Such "leaks" do not accumulate over time. Such "leaks" are not reported by garbage-collector-like leak detectors.

The primary design criterion for the default STL allocator was to make it no slower than the HP STL per-class allocators, but potentially thread-safe, and significantly less prone to fragmentation. Like the HP allocators, it does not maintain the necessary data structures to free entire chunks of small objects when none of the contained small objects are in use. This is an intentional choice of execution time over space use. It may not be appropriate for all programs. On many systems malloc_alloc may be more space efficient, and can be used when that is crucial.

The HP allocator design returned entire memory pools when the entire allocator was no longer needed. To allow this, it maintains a count of containers using a particular allocator. With the SGI design, this would only happen when the last container disappears, which is typically just before program exit. In most environments, this would be highly counterproductive; free would typically have to touch many long unreferenced pages just before the operating system reclaims them anyway. It would often introduce a significant delay on program exit, and would possibly page out large portions of other applications. There is nothing to be gained by this action, since the OS reclaims memory on program exit anyway, and it should do so without touching that memory.

In general, we recommend that leak detection tests be run with malloc_alloc. This yields more precise results with GC-based detectors (e.g. Pure Atria's PurifyTM), and it provides useful results even with detectors that simply count allocations and deallocations.


fill

Category: algorithms | Component type: function

Prototype

template <class ForwardIterator, class T>
void fill(ForwardIterator first, ForwardIterator last, const T& value);

Description

Fill assigns the value value to every element in the range [first, last). That is, for every iterator i in [first, last), it performs the assignment *i = value.

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

  • ForwardIterator is a model of Forward Iterator. [1]
  • ForwardIterator is mutable.
  • T is a model of Assignable.
  • T is convertible to Forward Iterator's value type.

Preconditions

  • [first, last) is a valid range.

Complexity

Linear. Fill performs exactly last - first assignments.

Example

vector<double> V(4);
fill(V.begin(), V.end(), 137);
assert(V[0] == 137 && V[1] == 137 && V[2] == 137 && V[3] == 137);

Notes

[1] The reason that fill requires its argument to be a mutable forward iterator, rather than merely an output iterator, is that it uses a range [first, last) of iterators. There is no sensible way to describe a range of output iterators, because it is impossible to compare two output iterators for equality. The fill_n algorithm does have an interface that permits use of an output iterator.

See also

copy, fill_n, generate, generate_n, iota


fill_n

Category: algorithms | Component type: function

Prototype

template <class OutputIterator, class Size, class T>
OutputIterator fill_n(OutputIterator first, Size n, const T& value);

Description

Fill_n assigns the value value to every element in the range [first, first+n). That is, for every iterator i in [first, first+n), it performs the assignment *i = value. The return value is first + n.

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

  • OutputIterator is a model of Output Iterator.
  • Size is an integral type (either signed or unsigned).
  • T is a model of Assignable.
  • T is convertible to a type in OutputIterator's set of value types.

Preconditions

  • n >= 0.
  • There is enough space to hold n values. That is, [first, first+n) is a valid range.

Complexity

Linear. Fill_n performs exactly n assignments.

Example

vector<double> V;
fill_n(back_inserter(V), 4, 137);
assert(V.size() == 4 && V[0] == 42 && V[1] == 42 && V[2] == 42 && V[3] == 42);

Notes

See also

copy, fill, generate, generate_n, iota


find

Category: algorithms | Component type: function

Prototype

template<class InputIterator, class EqualityComparable>
InputIterator find(InputIterator first, InputIterator last,
                   const EqualityComparable& value);

Description

Returns the first iterator i in the range [first, last) such that *i == value. Returns last if no such iterator exists.

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

  • EqualityComparable is a model of EqualityComparable.
  • InputIterator is a model of InputIterator.
  • Equality is defined between objects of type EqualityComparable and objects of InputIterator's value type.

Preconditions

  • [first, last) is a valid range.

Complexity

Linear: at most last - first comparisons for equality.

Example

list<int> L;
L.push_back(3);
L.push_back(1);
L.push_back(7);

list<int>::iterator result = find(L.begin(), L.end(), 7);
assert(result == L.end() || *result == 7);

Notes

See also

find_if.


find_end

Category: algorithms | Component type: function

Prototype

find_end is an overloaded name; there are actually two find_end functions.
template <class ForwardIterator1, class ForwardIterator2>
ForwardIterator1
find_end(ForwardIterator1 first1, ForwardIterator1 last1,
         ForwardIterator2 first2, ForwardIterator2 last2);

template <class ForwardIterator1, class ForwardIterator2,
          class BinaryPredicate>
ForwardIterator1
find_end(ForwardIterator1 first1, ForwardIterator1 last1,
         ForwardIterator2 first2, ForwardIterator2 last2,
         BinaryPredicate comp);

Description

Find_end is misnamed: it is much more similar to search than to find, and a more accurate name would have been search_end.

Like search, find_end attempts to find a subsequence within the range [first1, last1) that is identical to [first2, last2). The difference is that while search finds the first such subsequence, find_end finds the last such subsequence. Find_end returns an iterator pointing to the beginning of that subsequence; if no such subsequence exists, it returns last1.

The two versions of find_end differ in how they determine whether two elements are the same: the first uses operator==, and the second uses the user-supplied function object comp.

The first version of find_end returns the last iterator i in the range [first1, last1 - (last2 - first2)) such that, for every iterator j in the range [first2, last2), *(i + (j - first2)) == *j. The second version of find_end returns the last iterator i in [first1, last1 - (last2 - first2)) such that, for every iterator j in [first2, last2), binary_pred(*(i + (j - first2)), *j) is true. These conditions simply mean that every element in the subrange beginning with i must be the same as the corresponding element in [first2, last2).

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

For the first version:
  • ForwardIterator1 is a model of Forward Iterator.
  • ForwardIterator2 is a model of Forward Iterator.
  • ForwardIterator1's value type is a model of EqualityComparable.
  • ForwardIterator2's value type is a model of EqualityComparable.
  • Objects of ForwardIterator1's value type can be compared for equality with Objects of ForwardIterator2's value type.
For the second version:
  • ForwardIterator1 is a model of Forward Iterator.
  • ForwardIterator2 is a model of Forward Iterator.
  • BinaryPredicate is a model of Binary Predicate.
  • ForwardIterator1's value type is convertible to BinaryPredicate's first argument type.
  • ForwardIterator2's value type is convertible to BinaryPredicate's second argument type.

Preconditions

  • [first1, last1) is a valid range.
  • [first2, last2) is a valid range.

Complexity

The number of comparisons is proportional to (last1 - first1) * (last2 - first2). If both ForwardIterator1 and ForwardIterator2 are models of Bidirectional Iterator, then the average complexity is linear and the worst case is at most (last1 - first1) * (last2 - first2) comparisons.

Example

int main()
{
  char* s = "executable.exe";
  char* suffix = "exe";

  const int N = strlen(s);
  const int N_suf = strlen(suffix);

  char* location = find_end(s, s + N,
                            suffix, suffix + N_suf);

  if (location != s + N) {
    cout << "Found a match for " << suffix << " within " << s << endl;
    cout << s << endl;

    int i;
    for (i = 0; i < (location - s); ++i)
      cout << ' ';
    for (i = 0; i < N_suf; ++i)
      cout << '^';
    cout << endl;
  }
  else
    cout << "No match for " << suffix << " within " << s << endl;
}

Notes

[1] The reason that this range is [first1, last1 - (last2 - first2)), instead of simply [first1, last1), is that we are looking for a subsequence that is equal to the complete sequence [first2, last2). An iterator i can't be the beginning of such a subsequence unless last1 - i is greater than or equal to last2 - first2. Note the implication of this: you may call find_end with arguments such that last1 - first1 is less than last2 - first2, but such a search will always fail.

See also

search


find_first_of

Category: algorithms | Component type: function

Prototype

find_first_of is an overloaded name; there are actually two find_first_of functions.
template <class InputIterator, class ForwardIterator>
InputIterator find_first_of(InputIterator first1, InputIterator last1,
                            ForwardIterator first2, ForwardIterator last2);

template <class InputIterator, class ForwardIterator, class BinaryPredicate>
InputIterator find_first_of(InputIterator first1, InputIterator last1,
                            ForwardIterator first2, ForwardIterator last2,
                            BinaryPredicate comp);

Description

Find_first_of is similar to find, in that it performs linear seach through a range of Input Iterators. The difference is that while find searches for one particular value, find_first_of searches for any of several values. Specifically, find_first_of searches for the first occurrance in the range [first1, last1) of any of the elements in [first2, last2). (Note that this behavior is reminiscent of the function strpbrk from the standard C library.)

The two versions of find_first_of differ in how they compare elements for equality. The first uses operator==, and the second uses and arbitrary user-supplied function object comp. The first version returns the first iterator i in [first1, last1) such that, for some iterator j in [first2, last2), *i == *j. The second returns the first iterator i in [first1, last1) such that, for some iterator j in [first2, last2), comp(*i, *j) is true. As usual, both versions return last1 if no such iterator i exists.

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

For the first version:
  • InputIterator is a model of Input Iterator.
  • ForwardIterator is a model of Forward Iterator.
  • InputIterator's value type is EqualityComparable, and can be compared for equality with ForwardIterator's value type.
For the second version:
  • InputIterator is a model of Input Iterator.
  • ForwardIterator is a model of Forward Iterator.
  • BinaryPredicate is a model of Binary Predicate.
  • InputIterator's value type is convertible to BinaryPredicate's first argument type.
  • ForwardIterator's value type is convertible to BinaryPredicate's second argument type.

Preconditions

  • [first1, last1) is a valid range.
  • [first2, last2) is a valid range.

Complexity

At most (last1 - first1) * (last2 - first2) comparisons.

Example

Like strpbrk, one use for find_first_of is finding whitespace in a string; space, tab, and newline are all whitespace characters.
int main()
{
  const char* WS = "\t\n ";
  const int n_WS = strlen(WS);

  char* s1 = "This sentence contains five words.";
  char* s2 = "OneWord";

  char* end1 = find_first_of(s1, s1 + strlen(s1),
                             WS, WS + n_WS);
  char* end2 = find_first_of(s2, s2 + strlen(s2),
                             WS, WS + n_WS);

  printf("First word of s1: %.*s\n", end1 - s1, s1);
  printf("First word of s2: %.*s\n", end2 - s2, s2);
}

Notes

See also

find, find_if, search


find_if

Category: algorithms | Component type: function

Prototype

template<class InputIterator, class Predicate>
InputIterator find_if(InputIterator first, InputIterator last,
                      Predicate pred);

Description

Returns the first iterator i in the range [first, last) such that pred(*i) is true. Returns last if no such iterator exists.

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

  • Predicate is a model of Predicate.
  • InputIterator is a model of InputIterator.
  • The value type of InputIterator is convertible to the argument type of Predicate.

Preconditions

  • [first, last) is a valid range.
  • For each iterator i in the range [first, last), *i is in the domain of Predicate.

Complexity

Linear: at most last - first applications of Pred.

Example

list<int> L;
L.push_back(-3);
L.push_back(0);
L.push_back(3);
L.push_back(-2);

list<int>::iterator result = find_if(L.begin(), L.end(),
                                     bind2nd(greater<int>(), 0));
assert(result == L.end() || *result > 0);

Notes

See also

find.


Forward Container

Category: containers | Component type: concept

Description

A Forward Container is a Container whose elements are arranged in a definite order: the ordering will not change spontaneously from iteration to iteration. The requirement of a definite ordering allows the definition of element-by-element equality (if the container's element type is Equality Comparable) and of lexicographical ordering (if the container's element type is LessThan Comparable).

Iterators into a Forward Container satisfy the forward iterator requirements; consequently, Forward Containers support multipass algorithms and allow multiple iterators into the same container to be active at the same time.

Refinement of

Container, EqualityComparable, LessThanComparable

Associated types

No additional types beyond those defined in Container. However, the requirements for the iterator type are strengthened: the iterator type must be a model of Forward Iterator.

Notation

X | A type that is a model of Forward Container
a, b | Object of type X
T | The value type of X

Definitions

Valid expressions

In addition to the expressions defined in Container, EqualityComparable, and LessThanComparable, the following expressions must be valid.
Name | Expression | Type requirements | Return type
Equality | a == b | T is EqualityComparable | Convertible to bool
Inequality | a != b | T is EqualityComparable | Convertible to bool
Less | a < b | T is LessThanComparable | Convertible to bool
Greater | a > b | T is LessThanComparable | Convertible to bool
Less or equal | a <= b | T is LessThanComparable | Convertible to bool
Greater or equal | a >= b | T is LessThanComparable | Convertible to bool

Expression semantics

Semantics of an expression is defined only where it is not defined in Container, EqualityComparable, or LessThanComparable, or where there is additional information.
Name | Expression | Precondition | Semantics | Postcondition
Equality | a == b |  | Returns true if a.size() == b.size() and if each element of a compares equal to the corresponding element of b. Otherwise returns false. |
Less | a < b |  | Equivalent to lexicographical_compare(a,b) |

Complexity guarantees

The equality and inequality operations are linear in the container's size.

Invariants

Ordering Two different iterations through a forward container will access its elements in the same order, providing that there have been no intervening mutative operations.

Models

  • vector
  • list
  • slist
  • deque
  • set
  • hash_set
  • map
  • hash_map
  • multiset
  • hash_multiset
  • multimap
  • hash_multimap

Notes

See also

The iterator overview, Forward Iterator, Sequence


Forward Iterator

Category: iterators | Component type: concept

Description

A Forward Iterator is an iterator that corresponds to the usual intuitive notion of a linear sequence of values. It is possible to use Forward Iterators (unlike Input Iterators and Output Iterators) in multipass algorithms. Forward Iterators do not, however, allow stepping backwards through a sequence, but only, as the name suggests, forward.

A type that is a model of Forward Iterator may be either mutable or immutable, as defined in the Trivial Iterators requirements.

Refinement of

Input Iterator, Output Iterator

Associated types

The same as for Input Iterator

Notation

X | A type that is a model of Forward Iterator
T | The value type of X
i, j | Object of type X
t | Object of type T

Definitions

Valid expressions

Forward Iterator does not define any new expressions beyond those defined in Input Iterator. However, some of the restrictions described in Input Iterator are relaxed.
Name | Expression | Type requirements | Return type
Preincrement | ++i |  | X&
Postincrement | i++ |  | X

Expression semantics

Forward Iterator does not define any new expressions beyond those defined in Input Iterator. However, some of the restrictions described in Input Iterator are relaxed.
Name | Expression | Precondition | Semantics | Postcondition
Preincrement | ++i | i is dereferenceable | i points to the next value | i is dereferenceable or past-the-end. &i == &++i. If i == j, then ++i == ++j. [1]
Postincrement | i++ | i is dereferenceable | Equivalent to {X tmp = i; ++i; return tmp;} | i is dereferenceable or past-the-end. [1]

Complexity guarantees

The complexity of operations on Forward Iterators is guaranteed to be amortized constant time.

Invariants

Models

  • T*
  • hash_set<T>::iterator

Notes

[1] The restrictions described in Input Iterator have been removed. Incrementing a forward iterator does not invalidate copies of the old value and it is guaranteed that, if i and j are dereferenceable and i == j, then ++i == ++j. As a consequence of these two facts, it is possible to pass through the same Forward Iterator twice.

See also

Input Iterator, Output Iterator, Bidirectional Iterator, Random Access Iterator, Iterator overview


forward_iterator<T, Distance>

Category: iterators | Component type: type

Description

Forward_iterator is an iterator base class: it is intended that an iterator that is a model of Forward Iterator, and whose value type and distance type are T and Distance, may be defined by inheriting from forward_iterator<T, Distance> [1]. Forward_iterator is entirely empty: it has no member functions, member variables, or nested types. It exists solely to simplify the definition of the functions iterator_category, distance_type, and value_type.

Example

class my_forward_iterator : public forward_iterator<double>
{
  ...
};
This declares my_forward_iterator to be a Forward Iterator whose value type is double and whose distance type is ptrdiff_t. If Iter is an object of class my_forward_iterator, then iterator_category(Iter) will return forward_iterator_tag(), value_type(Iter) will return (double*) 0, and distance_type(Iter) will return (ptrdiff_t*) 0.

Definition

Defined in the standard header iterator, and in the nonstandard backward-compatibility header iterator.h. This class is no longer part of the C++ standard, although it was present in early drafts of the standard. It is retained in this implementation for backward compatibility.

Template parameters

Parameter | Description | Default
T | The iterator's value type |
Distance | The iterator's distance type | ptrdiff_t

Model of

Assignable

Public base classes

None

Type requirements

The distance type must be a signed integral type.

Public base classes

None.

Members

None.

New Members

None.

Notes

[1] It is not required that a Forward Iterator inherit from the base forward_iterator. It is, however, required that the functions iterator_category, distance_type, and value_type be defined for every Forward Iterator. (Or, if you are using the iterator_traits mechanism, that iterator_traits is properly specialized for every Forward Iterator.) Since those functions are defined for the base forward_iterator, the easiest way to ensure that are defined for a new type is to derive that class from forward_iterator and rely on the derived-to-base standard conversion of function arguments.

See also

The Iterator Tags overview, iterator_traits, iterator_category, value_type, distance_type, input_iterator, output_iterator, bidirectional_iterator, random_access_iterator


forward_iterator_tag

Category: iterators | Component type: type

Description

Forward_iterator_tag is an empty class: it has no member functions, member variables, or nested types. It is used solely as a "tag": a representation of the Forward Iterator concept within the C++ type system. Specifically, it is used as a return value for the function iterator_category. Iterator_category takes a single argument, an iterator, and returns an object whose type depends on the iterator's category. Iterator_category's return value is of type forward_iterator_tag if its argument is a Forward Iterator.

Example

See iterator_category

Definition

Defined in the standard header iterator, and in the nonstandard backward-compatibility header iterator.h.

Template parameters

None.

Model of

Assignable

Type requirements

None.

Public base classes

None.

Members

None.

New Members

None.

Notes

See also

iterator_category, Iterator Tags, iterator_traits, output_iterator_tag, input_iterator_tag, bidirectional_iterator_tag, random_access_iterator_tag


for_each

Category: algorithms | Component type: function

Prototype

template <class InputIterator, class UnaryFunction>
UnaryFunction for_each(InputIterator first, InputIterator last, UnaryFunction f);

Description

For_each applies the function object f to each element in the range [first, last); f's return value, if any, is ignored. Applications are performed in forward order, i.e. from first to last. For_each returns the function object after it has been applied to each element. [1]

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

  • InputIterator is a model of Input Iterator
  • UnaryFunction is a model of Unary Function
  • UnaryFunction does not apply any non-constant operation through its argument.
  • InputIterator's value type is convertible to UnaryFunction's argument type.

Preconditions

  • [first, last) is a valid range.

Complexity

Linear. Exactly last - first applications of UnaryFunction.

Example

template<class T> struct print : public unary_function<T, void>
{
  print(ostream& out) : os(out), count(0) {}
  void operator() (T x) { os << x << ' '; ++count; }
  ostream& os;
  int count;
};

int main()
{
  int A[] = {1, 4, 2, 8, 5, 7};
  const int N = sizeof(A) / sizeof(int);

  print<int> P = for_each(A, A + N, print<int>(cout));
  cout << endl << P.count << " objects printed." << endl;
}

Notes

[1] This return value is sometimes useful, since a function object may have local state. It might, for example, count the number of times that it is called, or it might have a status flag to indicate whether or not a call succeeded.

See also

The function object overview, count, copy


Front Insertion Sequence

Category: containers | Component type: concept

Description

A Front Insertion Sequence is a Sequence where it is possible to insert an element at the beginning, or to access the first element, in amortized constant time. Front Insertion Sequences have special member functions as a shorthand for those operations.

Refinement of

Sequence

Associated types

None, except for those of Sequence.

Notation

X | A type that is a model of Front Insertion Sequence
a | Object of type X
T | The value type of X
t | Object of type T

Definitions

Valid expressions

In addition to the expressions defined in Sequence, the following expressions must be valid.
Name | Expression | Type requirements | Return type
Front | a.front() [1] |  | reference if a is mutable, otherwise const_reference.
Push front | a.push_front(t) | a is mutable. | void
Pop front | a.pop_front() | a is mutable. | void

Expression semantics

Name | Expression | Precondition | Semantics | Postcondition
Front | a.front() [1] | !a.empty() | Equivalent to *(a.begin()). |
Push front | a.push_front(t) |  | Equivalent to a.insert(a.begin(), t) | a.size is incremented by 1. a.front() is a copy of t.
Pop front | a.pop_front() | !a.empty() | Equivalent to a.erase(a.begin()) | a.size() is decremented by 1.

Complexity guarantees

Front, push front, and pop front are amortized constant time. [2]

Invariants

Symmetry of push and pop push_front() followed by pop_front() is a null operation.

Models

  • list
  • deque

Notes

[1] Front is actually defined in Sequence, since it is always possible to implement it in amortized constant time. Its definition is repeated here, along with push front and pop front, in the interest of clarity.

[2] This complexity guarantee is the only reason that front(), push_front(), and pop_front() are defined: they provide no additional functionality. Not every sequence must define these operations, but it is guaranteed that they are efficient if they exist at all.

See also

Container, Sequence, Back Insertion Sequence, deque, list, slist


front_insert_iterator<FrontInsertionSequence>

Categories: iterators, adaptors | Component type: type

Description

Front_insert_iterator is an iterator adaptor that functions as an Output Iterator: assignment through a front_insert_iterator inserts an object before the first element of a Front Insertion Sequence. [1] [2]

Example

list<int> L;
L.push_front(3);
front_insert_iterator<list<int> > ii(L);
*ii++ = 0;
*ii++ = 1;
*ii++ = 2;
copy(L.begin(), L.end(), ostream_iterator<int>(cout, " "));
// The values that are printed are 2 1 0 3

Definition

Defined in the standard header iterator, and in the nonstandard backward-compatibility header iterator.h.

Template parameters

Parameter | Description | Default
FrontInsertionSequence | The type of Front Insertion Sequence into which values will be inserted. |

Model of

Output Iterator. A front insert iterator's set of value types (as defined in the Output Iterator requirements) consists of a single type: FrontInsertionSequence::value_type.

Type requirements

The template parameter FrontInsertionSequence must be a Front Insertion Sequence.

Public base classes

None.

Members

Member | Where defined | Description
front_insert_iterator(FrontInsertionSequence&) | front_insert_iterator | See below.
front_insert_iterator(const front_insert_iterator&) | Trivial Iterator | The copy constructor
front_insert_iterator&
operator=(const front_insert_iterator&)
Trivial Iterator The assignment operator
front_insert_iterator& operator*() | Output Iterator | Used to implement the output iterator expression *i = x. [3]
front_insert_iterator&
operator=(const FrontInsertionSequence::value_type&)
Output Iterator Used to implement the output iterator expression *i = x. [3]
front_insert_iterator& operator++() | Output Iterator | Preincrement.
front_insert_iterator& operator++(int) | Output Iterator | Postincrement.
output_iterator_tag
iterator_category(const front_insert_iterator&)
iterator tags Returns the iterator's category. This is a global function, not a member.
template<class FrontInsertionSequence>
front_insert_iterator<FrontInsertionSequence>
front_inserter(FrontInsertionSequence& S)
front_insert_iterator See below.

New members.

These members are not defined in the Output Iterator requirements, but are specific to front_insert_iterator.
Member | Description
front_insert_iterator(FrontInsertionSequence& S) | Constructs a front_insert_iterator that inserts objects before the first element of S.
template<class FrontInsertionSequence>
front_insert_iterator<FrontInsertionSequence>
front_inserter(FrontInsertionSequence& S);
Equivalent to front_insert_iterator<FrontInsertionSequence>(S). [4] This is a global function, not a member function.

Notes

[1] Note the difference between assignment through a FrontInsertionSequence::iterator and assignment through an front_insert_iterator<FrontInsertionSequence>. If i is a valid FrontInsertionSequence::iterator, then it points to some particular element in the front insertion sequence; the expression *i = t replaces that element with t, and does not change the total number of elements in the sequence. If ii is a valid front_insert_iterator<FrontInsertionSequence>, however, then the expression *ii = t is equivalent, for some FrontInsertionSequence seq, to the expression seq.push_front(t). That is, it does not overwrite any of seq's elements and it does change seq's size.

[2] Note the difference between a front_insert_iterator and an insert_iterator. It may seem that a front_insert_iterator is the same as an insert_iterator constructed with an insertion point that is the beginning of a sequence. In fact, though, there is a very important difference: every assignment through a front_insert_iterator corresponds to an insertion before the first element of the sequence. If you are inserting elements at the beginning of a sequence using an insert_iterator, then the elements will appear in the order in which they were inserted. If, however, you are inserting elements at the beginning of a sequence using a front_insert_iterator, then the elements will appear in the reverse of the order in which they were inserted.

[3] Note how assignment through an front_insert_iterator is implemented. In general, unary operator* must be defined so that it returns a proxy object, where the proxy object defines operator= to perform the insert operation. In this case, for the sake of simplicity, the proxy object is the front_insert_iterator itself. That is, *i simply returns i, and *i = t is equivalent to i = t. You should not, however, rely on this behavior. It is an implementation detail, and it is not guaranteed to remain the same in future versions.

[4] This function exists solely for the sake of convenience: since it is a non-member function, the template parameters may be inferred and the type of the front_insert_iterator need not be declared explicitly. One easy way to reverse a range and insert it at the beginning of a Front Insertion Sequence S, for example, is copy(first, last, front_inserter(S)).

See also

insert_iterator, back_insert_iterator, Output Iterator, Sequence, Front Insertion Sequence, Iterator overview


Function Objects

Category: functors | Component type: overview

Summary

A Function Object, or Functor (the two terms are synonymous) is simply any object that can be called as if it is a function. An ordinary function is a function object, and so is a function pointer; more generally, so is an object of a class that defines operator().

Description

The basic function object concepts are Generator, Unary Function, and Binary Function: these describe, respectively, objects that can be called as f(), f(x), and f(x,y). (This list could obviously be extended to ternary function and beyond, but, in practice, no STL algorithms require function objects of more than two arguments.) All other function object concepts defined by the STL are refinements of these three.

Function objects that return bool are an important special case. A Unary Function whose return type is bool is called a Predicate, and a Binary Function whose return type is bool is called a Binary Predicate.

There is an important distinction, but a somewhat subtle one, between function objects and adaptable function objects. [1] In general, a function object has restrictions on the type of its argument. The type restrictions need not be simple, though: operator() may be overloaded, or may be a member template, or both. Similarly, there need be no way for a program to determine what those restrictions are. An adaptable function object, however, does specify what the argument and return types are, and provides nested typedefs so that those types can be named and used in programs. If a type F0 is a model of Adaptable Generator, then it must define F0::result_type. Similarly, if F1 is a model of Adaptable Unary Function then it must define F1::argument_type and F1::result_type, and if F2 is a model of Adaptable Binary Function then it must define F2::first_argument_type, F2::second_argument_type, and F2::result_type. The STL provides base classes unary_function and binary_function to simplify the definition of Adaptable Unary Functions and Adaptable Binary Functions. [2]

Adaptable function objects are important because they can be used by function object adaptors: function objects that transform or manipulate other function objects. The STL provides many different function object adaptors, including unary_negate (which returns the logical complement of the value returned by a particular AdaptablePredicate), and unary_compose and binary_compose, which perform composition of function object.

Finally, the STL includes many different predefined function objects, including arithmetic operations (plus, minus, multiplies, divides, modulus, and negate), comparisons (equal_to, not_equal_to greater, less, greater_equal, and less_equal), and logical operations (logical_and, logical_or, and logical_not). It is possible to perform very sophisticated operations without actually writing a new function object, simply by combining predefined function objects and function object adaptors.

Examples

Fill a vector with random numbers. In this example, the function object is simply a function pointer.
    vector<int> V(100);
    generate(V.begin(), V.end(), rand);

Sort a vector of double by magnitude, i.e. ignoring the elements' signs. In this example, the function object is an object of a user-defined class.

    struct less_mag : public binary_function<double, double, bool> {
    bool operator()(double x, double y) { return fabs(x) < fabs(y); }
    };

    vector<double> V;
    ...
    sort(V.begin(), V.end(), less_mag());

Find the sum of elements in a vector. In this example, the function object is of a user-defined class that has local state.

    struct adder : public unary_function<double, void>
    {
      adder() : sum(0) {}
      double sum;
      void operator()(double x) { sum += x; }
    };

    vector<double> V;
    ...
    adder result = for_each(V.begin(), V.end(), adder()); [3]
    cout << "The sum is " << result.sum << endl;

Remove all elements from a list that are greater than 100 and less than 1000.

    list<int> L;
    ...
    list<int>::iterator new_end =
     remove_if(L.begin(), L.end(),
           compose2(logical_and<bool>(),
                bind2nd(greater<int>(), 100),
                bind2nd(less<int>(), 1000)));
    L.erase(new_end, L.end());

Concepts

  • Generator
  • Unary Function
  • Binary Function
  • Predicate
  • Binary Predicate
  • Adaptable Generator
  • Adaptable Unary Function
  • Adaptable Binary Function
  • Adaptable Predicate
  • Adaptable Binary Predicate

Types

  • plus
  • minus
  • multiplies (formerly called times)
  • divides
  • modulus,
  • negate
  • equal_to
  • not_equal_to
  • greater
  • less
  • greater_equal
  • less_equal,
  • logical_and
  • logical_or
  • logical_not
  • subtractive_rng
  • identity
  • project1st
  • project2nd
  • select1st
  • select2nd
  • unary_function
  • binary_function
  • unary_compose
  • binary_compose
  • unary_negate
  • binary_negate
  • binder1st
  • binder2nd
  • pointer_to_unary_function
  • pointer_to_binary_function

Functions

  • compose1
  • compose2
  • not1
  • not2
  • bind1st
  • bind2nd
  • ptr_fun

Notes

[1] The reason for the name "adaptable function object" is that adaptable function objects may be used by function object adaptors.

[2] The unary_function and binary_function bases are similar to the input_iterator, output_iterator, forward_iterator, bidirectional_iterator, and random_access_iterator bases: they are completely empty, and serve only to provide type information.

[3] This is an example of how to use function objects; it is not the recommended way of calculating the sum of elements in a vector. The accumulate algorithm is a better way of calculating a sum.

See also

[Silicon Surf] [STL Home]
Copyright © 1999 Silicon Graphics, Inc. All Rights Reserved. TrademarkInformation


generate

Category: algorithms | Component type: function

Prototype

template <class ForwardIterator, class Generator>
void generate(ForwardIterator first, ForwardIterator last, Generator gen);

Description

Generate assigns the result of invoking gen, a function object that takes no arguments, to each element in the range [first, last). [1]

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

  • ForwardIterator is a model of Forward Iterator. [2]
  • ForwardIterator is mutable.
  • Generator is a model of Generator.
  • Generator's result type is convertible to ForwardIterator's value type.

Preconditions

  • [first, last) is a valid range.

Complexity

Linear. Exactly last - first invocations of gen. [1]

Example

Fill a vector with random numbers, using the standard C library function rand.
vector<int> V;
...
generate(V.begin(), V.end(), rand);

Notes

[1] The function object gen is invoked for each iterator in the range [first, last), as opposed to just being invoked a single time outside the loop. This distinction is important because a Generator need not return the same result each time it is invoked; it is permitted to read from a file, refer to and modify local state, and so on.

[2] The reason that generate requires its argument to be a mutable Forward Iterator, rather than just an Output Iterator, is that it uses a range [first, last) of iterators. There is no sensible way to describe a range of Output Iterators, because it is impossible to compare two Output Iterators for equality. The generate_n algorithm does have an interface that permits use of an Output Iterator.

See also

copy, fill, fill_n, generate_n, iota


generate_n

Category: algorithms | Component type: function

Prototype

template <class OutputIterator, class Size, class Generator>
OutputIterator generate_n(OutputIterator first, Size n, Generator gen);

Description

Generate_n assigns the result of invoking gen, a function object that takes no arguments, to each element in the range [first, first+n). [1] The return value is first + n.

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

  • OutputIterator is a model of Output Iterator.
  • Size is an integral type (either signed or unsigned).
  • Generator is a model of Generator.
  • Generator's result type is convertible to a type in OutputIterator's set of value types.

Preconditions

  • n >= 0.
  • There is enough space to hold n values. That is, [first, first+n) is a valid range.

Complexity

Linear. Exactly n invocations of gen. [1]

Example

Print 100 random numbers, using the C standard library function rand.
generate_n(ostream_iterator<int>(cout, "\n"), 100, rand);

Notes

[1] The function object gen is invoked n times (once for each iterator in the range [first, first+n)), as opposed to just being invoked a single time outside the loop. This distinction is important because a Generator need not return the same result each time it is invoked; it is permitted to read from a file, refer to and modify local state, and so on.

See also

copy, fill, fill_n, generate, iota


Generator

Category: functors | Component type: concept

Description

A Generator is a kind of function object: an object that is called as if it were an ordinary C++ function. A Generator is called with no arguments.

Refinement of

Assignable

Associated types

Result type The type returned when the Generator is called

Notation

F | A type that is a model of Generator
Result | The result type of F
f | Object of type F

Definitions

The range of a Generator is the set of all possible value that it may return.

Valid expressions

Name | Expression | Type requirements | Return type
Function call | f() |  | Result

Expression semantics

Name | Expression | Precondition | Semantics | Postcondition
Function call | f() |  | Returns some value of type Result [1] | The return value is in f's range.

Complexity guarantees

Invariants

Models

  • Result (*)()

Notes

[1] Two different invocations of f may return different results: a Generator may refer to local state, perform I/O, and so on. The expression f() is permitted to change f's state; f might, for example, represent a pseudo-random number generator.

See also

Function Object overview, Unary Function, Binary Function, Adaptable Generator


get_temporary_buffer

Category: allocators | Component type: function

Prototype

template <class T>
pair<T*, ptrdiff_t> get_temporary_buffer(ptrdiff_t len, T*);

Description

Some algorithms, such as stable_sort and inplace_merge, are adaptive: they attempt to use extra temporary memory to store intermediate results, and their run-time complexity is better if that extra memory is available.

The first argument to get_temporary_buffer specifies the requested size of the temporary buffer, and the second specifies the type of object that will be stored in the buffer. That is, get_temporary_buffer(len, (T*) 0) requests a buffer that is aligned for objects of type T and that is large enough to hold len objects of type T. [1]

The return value of get_temporary_buffer is a pair P whose first component is a pointer to the temporary buffer and whose second argument indicates how large the buffer is: the buffer pointed to by P.first is large enough to hold P.second objects of type T. P.second is greater than or equal to 0 [2], and less than or equal to len [1]. Note that P.first is a pointer to uninitialized memory, rather than to actual objects of type T; this memory can be initialized using uninitialized_copy, uninitialized_fill, or uninitialized_fill_n.

As the name suggests, get_temporary_buffer should only be used to obtain temporary memory. If a function allocates memory using get_temporary_buffer, then it must deallocate that memory, using return_temporary_buffer [3], before it returns.

Note: get_temporary_buffer and return_temporary_buffer are only provided for backward compatibility. If you are writing new code, you should instead use the temporary_buffer class.

Definition

Defined in the standard header memory, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

Preconditions

  • len is greater than 0.

Complexity

Example

int main()
{
  pair<int*, ptrdiff_t> P = get_temporary_buffer(10000, (int*) 0);
  int* buf = P.first;
  ptrdiff_t N = P.second;
  uninitialized_fill_n(buf, N, 42);
  int* result = find_if(buf, buf + N, bind2nd(not_equal_to<int>(), 42));
  assert(result == buf + N);
  return_temporary_buffer(buf);
}

Notes

[1] The argument len is a request, rather than a requirement. The intention is that get_temporary_buffer will return as large a buffer as can be allocated without hurting performance. Note that determining this maximum size is quite difficult: it depends on cache size, physical versus virtual memory, heap fragmentation, and so on. A good implementation of get_temporary_buffer must be nonportable.

[2] If P.second is 0, this means that get_temporary_buffer was unable to allocate a temporary buffer at all. In that case, P.first is a null pointer.

[3] It is unspecified whether get_temporary_buffer is implemented using malloc, or ::operator new, or some other method. The only portable way to return memory that was allocated using get_temporary_buffer is to use return_temporary_buffer.

See also

temporary_buffer, return_temporary_buffer, Allocators


greater<T>

Category: functors | Component type: type

Description

Greater<T> is a function object. Specifically, it is an Adaptable Binary Predicate, which means it is a function object that tests the truth or falsehood of some condition. If f is an object of class greater<T> and x and y are objects of class T, then f(x,y) returns true if x > y and false otherwise.

Example

Sort a vector in descending order, rather than the default ascending order.
vector<int> V;
...
sort(V.begin(), V.end(), greater<int>());

Definition

Defined in the standard header functional, and in the nonstandard backward-compatibility header function.h.

Template parameters

Parameter | Description | Default
T | The type of greater's arguments. |

Model of

Adaptable Binary Predicate, DefaultConstructible

Type requirements

T is LessThan Comparable.

Public base classes

binary_function<T, T, bool>.

Members

Member | Where defined | Description
first_argument_type | Adaptable Binary Predicate | The type of the first argument: T
second_argument_type | Adaptable Binary Predicate | The type of the second argument: T
result_type | Adaptable Binary Predicate | The type of the result: bool
greater() | DefaultConstructible | The default constructor.
bool operator()(const T& x, const T& y) | Binary Function | Function call operator. The return value is x > y.

New members

All of greater's members are defined in the Adaptable Binary Predicate and DefaultConstructible requirements. Greater does not introduce any new members.

Notes

See also

The function object overview, Adaptable Binary Predicate, LessThan Comparable, equal_to, not_equal_to, less, greater_equal, less_equal


greater_equal<T>

Category: functors | Component type: type

Description

Greater_equal<T> is a function object. Specifically, it is an Adaptable Binary Predicate, which means it is a function object that tests the truth or falsehood of some condition. If f is an object of class greater_equal<T> and x and y are objects of class T, then f(x,y) returns true if x >= y and false otherwise.

Example

Find the first nonnegative element in a list.
list<int> L;
...
list<int>::iterator first_nonnegative =
    find_if(L.begin(), L.end(), bind2nd(greater_equal<int>(), 0));
assert(first_nonnegative == L.end() || *first_nonnegative >= 0);

Definition

Defined in the standard header functional, and in the nonstandard backward-compatibility header function.h.

Template parameters

Parameter | Description | Default
T | The type of greater_equal's arguments. |

Model of

Adaptable Binary Predicate, DefaultConstructible

Type requirements

T is LessThan Comparable.

Public base classes

binary_function<T, T, bool>.

Members

Member | Where defined | Description
first_argument_type | Adaptable Binary Predicate | The type of the first argument: T
second_argument_type | Adaptable Binary Predicate | The type of the second argument: T
result_type | Adaptable Binary Predicate | The type of the result: bool
greater_equal() | DefaultConstructible | The default constructor.
bool operator()(const T& x, const T& y) | Binary Function | Function call operator. The return value is x >= y.

New members

All of greater_equal's members are defined in the Adaptable Binary Predicate and DefaultConstructible requirements. Greater_equal does not introduce any new members.

Notes

See also

The function object overview, Adaptable Binary Predicate, equal_to, not_equal_to, greater less, less_equal


hash<T>

Categories: containers, functors | Component type: type

Description

The function object hash<T> is a Hash Function; it is used as the default hash function by all of the Hashed Associative Containers that are included in the STL.

The hash<T> template is only defined for template arguments of type char*, const char*, crope, wrope, and the built-in integral types. [1] If you need a Hash Function with a different argument type, you must either provide your own template specialization or else use a different Hash Function.

Example

int main()
{
  hash<const char*> H;
  cout << "foo -> " << H("foo") << endl;
  cout << "bar -> " << H("bar") << endl;
}

Definition

Defined in the headers hash_map and hash_set, and in the backward-compatibility headers hash_map.h and hash_set.h. This class is an SGI extension; it is not part of the C++ standard.

Template parameters

Parameter | Description | Default
T | The argument type. That is, the type of object that is being hashed. |

Model of

Hash Function

Type requirements

T must be a type for which a specialization of hash has been defined. The STL defines the following specializations:
  • char*
  • const char*
  • crope
  • wrope
  • char
  • signed char
  • unsigned char
  • short
  • unsigned short
  • int
  • unsigned int
  • long
  • unsigned long

Public base classes

None.

Members

Member | Where defined | Description
size_t operator()(const T& x) | Hash Function | Returns x's hash value.

New members

All of hash's members are defined in the Hash Function requirements. Hash does not introduce any new members.

Notes

[1] Technically, what this means is that the actual template hash<T> is an empty class; the member function operator() is defined only in the various specializations.

See also

Hashed Associative Container, Hash Function


Hashed Associative Container

Category: containers | Component type: concept

Description

A Hashed Associative Container is an Associative Container whose implementation is a hash table. [1] The elements of a Hashed Associative Container are not guaranteed to be in any meaningful order; in particular, they are not sorted. The worst case complexity of most operations on Hashed Associative Containers is linear in the size of the container, but the average case complexity is constant time; this means that for applications where values are simply stored and retrieved, and where ordering is unimportant, Hashed Associative Containers are usually much faster than Sorted Associative Containers.

Refinement of

Associative Container

Associated types

The following new types are introduced, in addition to the types defined in the Associative Container requirements.
Hash function | X::hasher | A type that is a model of Hash Function. X::hasher's argument type must be X::key_type.
Key equal | X::key_equal | A Binary Predicate whose argument type is X::key_type. An object of type key_equal returns true if its arguments are the same key, and false otherwise. X::key_equal must be an equivalence relation.

Notation

X | A type that is a model of Hashed Associative Container
a | Object of type X
t | Object of type X::value_type
k | Object of type X::key_type
p, q | Object of type X::iterator
n | Object of type X::size_type
h | Object of type X::hasher
c | Object of type X::key_equal

Definitions

A hash function for a Hashed Associative Container X is a Unary Function whose argument type is X::key_type and whose return type is size_t. A hash function must be deterministic (that is, it must always return the same value whenever it is called with the same argument), but return values of the hash function should be as uniform as possible: ideally, no two keys will hash to the same value. [2]

Elements in a Hashed Associative Container are organized into buckets. A Hashed Associative Container uses the value of the hash function to determine which bucket an element is assigned to.

The number of elements in a Hashed Associative Container divided by the number of buckets is called the load factor. A Hashed Associative Container with a small load factor is faster than one with a large load factor.

Valid expressions

In addition to the expressions defined in Associative Container, the following expressions must be valid.
Name | Expression | Type requirements | Return type
Default constructor
X()
X a;
Constructor with bucket count
X(n)
X a(n);
Constructor with hash function
X(n, h)
X a(n, h);
Constructor with key equal
X(n, h, k)
X a(n, h, k);
Hash function | a.hash_funct() | X::hasher
Key equal | a.key_eq() | X::key_equal
Erase key | a.erase(k) | size_type
Erase element | a.erase(p) | void
Erase range | a.erase(p, q) | void
Find | a.find(k) | iterator if a is mutable, otherwise const_iterator
Count | a.count(k) | size_type
Equal range | a.equal_range(k) | pair<iterator, iterator> if a is mutable, otherwise pair<const_iterator, const_iterator>.
Bucket count | a.bucket_count() | X::size_type
Resize | a.resize(n) | void

Expression semantics

Name | Expression | Precondition | Semantics | Postcondition
Default constructor
X()
X a;
Creates an empty container, using hasher() as the hash function and key_equal() as the key equality function. The size of the container is 0. The bucket count is an unspecified default value. The hash function is hasher(), and the key equality function is key_equal().
Constructor with bucket count
X(n)
X a(n);
Creates an empty container with at least n buckets, using hasher() as the hash function and key_equal() as the key equality function. The size of the container is 0. The bucket count is greater than or equal to n. The hash function is hasher(), and the key equality function is key_equal().
Constructor with hash function
X(n, h)
X a(n, h);
Creates an empty container with at least n buckets, using h as the hash function and key_equal() as the key equality function. The size of the container is 0. The bucket count is greater than or equal to n. The hash function is h, and the key equality function is key_equal().
Constructor with key equal
X(n, h, k)
X a(n, h, k);
Creates an empty container with at least n buckets, using h as the hash function and k as the key equality function. The size of the container is 0. The bucket count is greater than or equal to n. The hash function is h, and the key equality function is k.
Hash function | a.hash_funct() | Returns the hash function used by a.
Key equal | a.key_eq() | Returns the key equal function used by a.
Erase key | a.erase(k) | Destroys all elements whose key is the same as k, and removes them from a. [2] The return value is the number of elements that were erased, i.e. the old value of a.count(k). | a.size() is decremented by a.count(k). a contains no elements with key k.
Erase element | a.erase(p) | p is a dereferenceable iterator in a. | Destroys the element pointed to by p, and removes it from a. | a.size() is decremented by 1.
Erase range | a.erase(p, q) | [p, q) is a valid range in a. | Destroys the elements in the range [p,q) and removes them from a. | a.size() is decremented by the distance from i to j.
Find | a.find(k) | Returns an iterator pointing to an element whose key is the same as k, or a.end() if no such element exists. | Either the return value is a.end(), or else the return value has a key that is the same as k.
Count | a.count(k) | Returns the number of elements in a whose keys are the same as k.
Equal range | a.equal_range(k) | Returns a pair P such that [P.first, P.second) is a range containing all elements in a whose keys are the same as k. [3] If no elements have the same key as k, the return value is an empty range. | The distance between P.first and P.second is equal to a.count(k). If p is a dereferenceable iterator in a, then either a lies in the range [P.first, P.second), or else *a has a key that is not the same as k.
Bucket count | a.bucket_count() | Returns the number of buckets in a.
Resize | a.resize(n) | Increases the bucket count of a. | The bucket count of a will be at least n. All iterators pointing to element in a will remain valid. [3]

Complexity guarantees

The default constructor, constructor with bucket count, constructor with hash function, and constructor with key equal, are all amortized constant time.

Hash Function and Key Equal are amortized constant time.

Average complexity for Erase Key is O(count(k)). Worst case is linear in the size of the container.

Erase Element is amortized constant time.

Average complexity for Erase Range is O(N), where N is the length of the range being erased. Worse case is linear in the size of the container.

Average complexity for Find is constant time. Worst case is linear in the size of the container.

Average complexity for Equal Range is O(count(k)). Worst case is linear in the size of the container.

Average complexity for Count is O(count(k)). Worst case is linear in the size of the container.

Bucket Count is amortized constant time.

Resize is linear in the size of the container.

Invariants

Models

  • hash_set
  • hash_map
  • hash_multiset
  • hash_multimap

Notes

[1] There is an extensive literature dealing with hash tables. See, for example, section 6.4 of Knuth. (D. E. Knuth, The Art of Computer Programming. Volume 3: Sorting and Searching. Addison-Wesley, 1975.)

[2] If the hash function is poor (that is, if many different keys hash to the same value) then this will hurt performance. The worst case is where every key hashes to the same value; in this case, run-time complexity of most Hashed Associative Container operations will be linear in the size of the container.

[3] Resizing does not invalidate iterators; however, it does not necessarily preserve the ordering relation between iterators. That is, if i and j are iterators that point into a Hashed Associative Container such that i comes immediately before j, then there is no guarantee that i will still come immediately before j after the container is resized. The only guarantee about about the ordering of elements is the contiguous storage invariant: elements with the same key are always adjacent to each other.

See also

Associative Container, Sorted Associative Container, Unique Hashed Associative Container, Multiple Hashed Associative Container,


Hash Function

Categories: containers, functors | Component type: concept

Description

A Hash Function is a Unary Function that is used by Hashed Associative Containers: it maps its argument to a result of type size_t. A Hash Function must be deterministic and stateless. That is, the return value must depend only on the argument, and equal arguments must yield equal results.

The performance of a Hashed Associative Container depends crucially on its hash function. It is important for a Hash Function to minimize collisions, where a collision is defined as two different arguments that hash to the same value. It is also important that the distribution of hash values be uniform; that is, the probability that a Hash Function returns any particular value of type size_t should be roughly the same as the probability that it returns any other value. [1]

Refinement of

Unary Function

Associated types

Result type The type returned when the Hash Function is called. The result type must be size_t.

Notation

Definitions

Valid expressions

None, except for those described in the Unary Function requirements.

Expression semantics

Complexity guarantees

Invariants

Deterministic function The return value depends only on the argument, as opposed to the past history of the Hash Function object. The return value is always the same whenever the argument is the same.

Models

  • hash

Notes

[1] Note that both of these requirements make sense only in the context of some specific distribution of input values. To take a simple example, suppose that the values being hashed are the six strings "aardvark", "trombone", "history", "diamond", "forthright", and "solitude". In this case, one reasonable (and efficient) hash function would simply be the first character of each string. On the other hand, suppose that the values being hashed are "aaa0001", "aaa0010", "aaa0011", "aaa0100", "aaa0101", and "aaa0110". In that case, a different hash function would be more appropriate. This is why Hashed Associative Containers are parameterized by the hash function: no one hash function is best for all applications.

See also

Hashed Associative Container, hash


hash_map<Key, Data, HashFcn, EqualKey, Alloc>

Category: containers | Component type: type

Description

Hash_map is a Hashed Associative Container that associates objects of type Key with objects of type Data. Hash_map is a Pair Associative Container, meaning that its value type is pair<const Key, Data>. It is also a Unique Associative Container, meaning that no two elements have keys that compare equal using EqualKey.

Looking up an element in a hash_map by its key is efficient, so hash_map is useful for "dictionaries" where the order of elements is irrelevant. If it is important for the elements to be in a particular order, however, then map is more appropriate.

Example

struct eqstr
{
  bool operator()(const char* s1, const char* s2) const
  {
    return strcmp(s1, s2) == 0;
  }
};

int main()
{
  hash_map<const char*, int, hash<const char*>, eqstr> months;

  months["january"] = 31;
  months["february"] = 28;
  months["march"] = 31;
  months["april"] = 30;
  months["may"] = 31;
  months["june"] = 30;
  months["july"] = 31;
  months["august"] = 31;
  months["september"] = 30;
  months["october"] = 31;
  months["november"] = 30;
  months["december"] = 31;

  cout << "september -> " << months["september"] << endl;
  cout << "april     -> " << months["april"] << endl;
  cout << "june      -> " << months["june"] << endl;
  cout << "november  -> " << months["november"] << endl;
}

Definition

Defined in the header hash_map, and in the backward-compatibility header hash_map.h. This class is an SGI extension; it is not part of the C++ standard.

Template parameters

Parameter | Description | Default
Key | The hash_map's key type. This is also defined as hash_map::key_type. |
Data | The hash_map's data type. This is also defined as hash_map::data_type. |
HashFcn | The hash function used by the hash_map. This is also defined as hash_map::hasher. | hash<Key>
EqualKey | The hash_map key equality function: a binary predicate that determines whether two keys are equal. This is also defined as hash_map::key_equal. | equal_to<Key>
Alloc | The hash_map's allocator, used for all internal memory management. | alloc

Model of

Unique Hashed Associative Container, Pair Associative Container

Type requirements

  • Key is Assignable.
  • EqualKey is a Binary Predicate whose argument type is Key.
  • EqualKey is an equivalence relation.
  • Alloc is an Allocator.

Public base classes

None.

Members

Member | Where defined | Description
key_type | Associative Container | The hash_map's key type, Key.
data_type | Pair Associative Container | The type of object associated with the keys.
value_type | Pair Associative Container | The type of object, pair<const key_type, data_type>, stored in the hash_map.
hasher | Hashed Associative Container | The hash_map's hash function.
key_equal | Hashed Associative Container | Function object that compares keys for equality.
pointer | Container | Pointer to T.
reference | Container | Reference to T
const_reference | Container | Const reference to T
size_type | Container | An unsigned integral type.
difference_type | Container | A signed integral type.
iterator | Container | Iterator used to iterate through a hash_map. [1]
const_iterator | Container | Const iterator used to iterate through a hash_map.
iterator begin() | Container | Returns an iterator pointing to the beginning of the hash_map.
iterator end() | Container | Returns an iterator pointing to the end of the hash_map.
const_iterator begin() const | Container | Returns an const_iterator pointing to the beginning of the hash_map.
const_iterator end() const | Container | Returns an const_iterator pointing to the end of the hash_map.
size_type size() const | Container | Returns the size of the hash_map.
size_type max_size() const | Container | Returns the largest possible size of the hash_map.
bool empty() const | Container | true if the hash_map's size is 0.
size_type bucket_count() const | Hashed Associative Container | Returns the number of buckets used by the hash_map.
void resize(size_type n) | Hashed Associative Container | Increases the bucket count to at least n.
hasher hash_funct() const | Hashed Associative Container | Returns the hasher object used by the hash_map.
key_equal key_eq() const | Hashed Associative Container | Returns the key_equal object used by the hash_map.
hash_map() | Container | Creates an empty hash_map.
hash_map(size_type n) | Hashed Associative Container | Creates an empty hash_map with at least n buckets.
hash_map(size_type n,
         const hasher& h)
Hashed Associative Container Creates an empty hash_map with at least n buckets, using h as the hash function.
hash_map(size_type n,
         const hasher& h,
         const key_equal& k)
Hashed Associative Container Creates an empty hash_map with at least n buckets, using h as the hash function and k as the key equal function.
template <class InputIterator>
hash_map(InputIterator f, InputIterator l)
[2]
Unique Hashed Associative Container Creates a hash_map with a copy of a range.
template <class InputIterator>
hash_map(InputIterator f, InputIterator l,
         size_type n)
[2]
Unique Hashed Associative Container Creates a hash_map with a copy of a range and a bucket count of at least n.
template <class InputIterator>
hash_map(InputIterator f, InputIterator l,
         size_type n, const hasher& h)
[2]
Unique Hashed Associative Container Creates a hash_map with a copy of a range and a bucket count of at least n, using h as the hash function.
template <class InputIterator>
hash_map(InputIterator f, InputIterator l,
         size_type n, const hasher& h,
         const key_equal& k)
[2]
Unique Hashed Associative Container Creates a hash_map with a copy of a range and a bucket count of at least n, using h as the hash function and k as the key equal function.
hash_map(const hash_map&) | Container | The copy constructor.
hash_map& operator=(const hash_map&) | Container | The assignment operator
void swap(hash_map&) | Container | Swaps the contents of two hash_maps.
pair<iterator, bool>
insert(const value_type& x)
Unique Associative Container Inserts x into the hash_map.
template <class InputIterator>
void insert(InputIterator f, InputIterator l)
[2]
Unique Associative Container Inserts a range into the hash_map.
void erase(iterator pos) | Associative Container | Erases the element pointed to by pos.
size_type erase(const key_type& k) | Associative Container | Erases the element whose key is k.
void erase(iterator first, iterator last) | Associative Container | Erases all elements in a range.
void clear() | Associative Container | Erases all of the elements.
const_iterator find(const key_type& k) const | Associative Container | Finds an element whose key is k.
iterator find(const key_type& k) | Associative Container | Finds an element whose key is k.
size_type count(const key_type& k) const | Unique Associative Container | Counts the number of elements whose key is k.
pair<const_iterator, const_iterator>
equal_range(const key_type& k) const
Associative Container Finds a range containing all elements whose key is k.
pair<iterator, iterator>
equal_range(const key_type& k)
Associative Container Finds a range containing all elements whose key is k.
data_type&
operator[](const key_type& k) [3]
hash_map See below.
bool operator==(const hash_map&,
                const hash_map&)
Hashed Associative Container Tests two hash_maps for equality. This is a global function, not a member function.

New members

These members are not defined in the Unique Hashed Associative Container and Pair Associative Container requirements, but are specific to hash_map.
Member Description
data_type&
operator[](const key_type& k) [3]
Returns a reference to the object that is associated with a particular key. If the hash_map does not already contain such an object, operator[] inserts the default object data_type(). [3]

Notes

[1] Hash_map::iterator is not a mutable iterator, because hash_map::value_type is not Assignable. That is, if i is of type hash_map::iterator and p is of type hash_map::value_type, then *i = p is not a valid expression. However, hash_map::iterator isn't a constant iterator either, because it can be used to modify the object that it points to. Using the same notation as above, (*i).second = p is a valid expression.

[2] This member function relies on member template functions, which at present (early 1998) are not supported by all compilers. If your compiler supports member templates, you can call this function with any type of input iterator. If your compiler does not yet support member templates, though, then the arguments must either be of type const value_type* or of type hash_map::const_iterator.

[3] Since operator[] might insert a new element into the hash_map, it can't possibly be a const member function. Note that the definition of operator[] is extremely simple: m[k] is equivalent to (*((m.insert(value_type(k, data_type()))).first)).second. Strictly speaking, this member function is unnecessary: it exists only for convenience.

See also

Associative Container, Hashed Associative Container, Pair Associative Container, Unique Hashed Associative Container, set, map multiset, multimap, hash_set, hash_multiset, hash_multimap


hash_multimap<Key, Data, HashFcn, EqualKey, Alloc>

Category: containers | Component type: type

Description

Hash_multimap is a Hashed Associative Container that associates objects of type Key with objects of type Data. Hash_multimap is a Pair Associative Container, meaning that its value type is pair<const Key, Data>. It is also a Multiple Associative Container, meaning that there is no limit on the number of elements whose keys may compare equal using EqualKey.

Looking up an element in a hash_multimap by its key is efficient, so hash_multimap is useful for "dictionaries" where the order of elements is irrelevant. If it is important for the elements to be in a particular order, however, then multimap is more appropriate.

Example

struct eqstr
{
  bool operator()(const char* s1, const char* s2) const
  {
    return strcmp(s1, s2) == 0;
  }
};

typedef hash_multimap<const char*, int, hash<const char*>, eqstr> map_type;

void lookup(const map_type& Map, const char* str)
{
  cout << str << ": ";
  pair<map_type::const_iterator, map_type::const_iterator> p =
    Map.equal_range(str);
  for (map_type::const_iterator i = p.first; i != p.second; ++i)
    cout << (*i).second << " ";
  cout << endl;
}

int main()
{
  map_type M;
  M.insert(map_type::value_type("H", 1));
  M.insert(map_type::value_type("H", 2));
  M.insert(map_type::value_type("C", 12));
  M.insert(map_type::value_type("C", 13));
  M.insert(map_type::value_type("O", 16));
  M.insert(map_type::value_type("O", 17));
  M.insert(map_type::value_type("O", 18));
  M.insert(map_type::value_type("I", 127));

  lookup(M, "I");
  lookup(M, "O");
  lookup(M, "Rn");
}

Definition

Defined in the header hash_map, and in the backward-compatibility header hash_map.h. This class is an SGI extension; it is not part of the C++ standard.

Template parameters

Parameter | Description | Default
Key | The hash_multimap's key type. This is also defined as hash_multimap::key_type. |
Data | The hash_multimap's data type. This is also defined as hash_multimap::data_type. |
HashFcn | The hash function used by the hash_multimap. This is also defined as hash_multimap::hasher. | hash<Key>
EqualKey | The hash_multimap's key equality function: a binary predicate that determines whether two keys are equal. This is also defined as hash_multimap::key_equal. | equal_to<Key>
Alloc | The hash_set's allocator, used for all internal memory management. | alloc

Model of

Multiple Hashed Associative Container, Pair Associative Container

Type requirements

  • Key is Assignable.
  • EqualKey is a Binary Predicate whose argument type is Key.
  • EqualKey is an equivalence relation.
  • Alloc is an Allocator.

Public base classes

None.

Members

Member | Where defined | Description
key_type | Associative Container | The hash_multimap's key type, Key.
data_type | Pair Associative Container | The type of object associated with the keys.
value_type | Pair Associative Container | The type of object, pair<const key_type, data_type>, stored in the hash_multimap.
hasher | Hashed Associative Container | The hash_multimap's hash function.
key_equal | Hashed Associative Container | Function object that compares keys for equality.
pointer | Container | Pointer to T.
reference | Container | Reference to T
const_reference | Container | Const reference to T
size_type | Container | An unsigned integral type.
difference_type | Container | A signed integral type.
iterator | Container | Iterator used to iterate through a hash_multimap. [1]
const_iterator | Container | Const iterator used to iterate through a hash_multimap.
iterator begin() | Container | Returns an iterator pointing to the beginning of the hash_multimap.
iterator end() | Container | Returns an iterator pointing to the end of the hash_multimap.
const_iterator begin() const | Container | Returns an const_iterator pointing to the beginning of the hash_multimap.
const_iterator end() const | Container | Returns an const_iterator pointing to the end of the hash_multimap.
size_type size() const | Container | Returns the size of the hash_multimap.
size_type max_size() const | Container | Returns the largest possible size of the hash_multimap.
bool empty() const | Container | true if the hash_multimap's size is 0.
size_type bucket_count() const | Hashed Associative Container | Returns the number of buckets used by the hash_multimap.
void resize(size_type n) | Hashed Associative Container | Increases the bucket count to at least n.
hasher hash_funct() const | Hashed Associative Container | Returns the hasher object used by the hash_multimap.
key_equal key_eq() const | Hashed Associative Container | Returns the key_equal object used by the hash_multimap.
hash_multimap() | Container | Creates an empty hash_multimap.
hash_multimap(size_type n) | Hashed Associative Container | Creates an empty hash_multimap with at least n buckets.
hash_multimap(size_type n,
              const hasher& h)
Hashed Associative Container Creates an empty hash_multimap with at least n buckets, using h as the hash function.
hash_multimap(size_type n,
              const hasher& h,
              const key_equal& k)
Hashed Associative Container Creates an empty hash_multimap with at least n buckets, using h as the hash function and k as the key equal function.
template <class InputIterator>
hash_multimap(InputIterator, InputIterator)
[2]
Multiple Hashed Associative Container Creates a hash_multimap with a copy of a range.
template <class InputIterator>
hash_multimap(InputIterator, InputIterator,
              size_type n)
[2]
Multiple Hashed Associative Container Creates a hash_multimap with a copy of a range and a bucket count of at least n.
template <class InputIterator>
hash_multimap(InputIterator, InputIterator,
              size_type n, const hasher& h)
[2]
Multiple Hashed Associative Container Creates a hash_multimap with a copy of a range and a bucket count of at least n, using h as the hash function.
template <class InputIterator>
hash_multimap(InputIterator, InputIterator,
              size_type n, const hasher& h,
              const key_equal& k)
[2]
Multiple Hashed Associative Container Creates a hash_multimap with a copy of a range and a bucket count of at least n, using h as the hash function and k as the key equal function.
hash_multimap(const hash_multimap&) | Container | The copy constructor.
hash_multimap& operator=(const hash_multimap&) | Container | The assignment operator
void swap(hash_multimap&) | Container | Swaps the contents of two hash_multimaps.
iterator insert(const value_type& x) | Multiple Associative Container | Inserts x into the hash_multimap.
template <class InputIterator>
void insert(InputIterator, InputIterator)
[2]
Multiple Associative Container Inserts a range into the hash_multimap.
void erase(iterator pos) | Associative Container | Erases the element pointed to by pos.
size_type erase(const key_type& k) | Associative Container | Erases the element whose key is k.
void erase(iterator first, iterator last) | Associative Container | Erases all elements in a range.
void clear() | Associative Container | Erases all of the elements.
const_iterator find(const key_type& k) const | Associative Container | Finds an element whose key is k.
iterator find(const key_type& k) | Associative Container | Finds an element whose key is k.
size_type count(const key_type& k) const | Associative Container | Counts the number of elements whose key is k.
pair<const_iterator, const_iterator>
equal_range(const key_type& k) const
Associative Container Finds a range containing all elements whose key is k.
pair<iterator, iterator>
equal_range(const key_type& k)
Associative Container Finds a range containing all elements whose key is k.
bool operator==(const hash_multimap&,
                const hash_multimap&)
Hashed Associative Container Tests two hash_multimaps for equality. This is a global function, not a member function.

New members

All of hash_multimap's members are defined in the Multiple Hashed Associative Container and Pair Associative Container requirements. Hash_multimap does not introduce any new members.

Notes

[1] Hash_multimap::iterator is not a mutable iterator, because hash_multimap::value_type is not Assignable. That is, if i is of type hash_multimap::iterator and p is of type hash_multimap::value_type, then *i = p is not a valid expression. However, hash_multimap::iterator isn't a constant iterator either, because it can be used to modify the object that it points to. Using the same notation as above, (*i).second = p is a valid expression.

[2] This member function relies on member template functions, which at present (early 1998) are not supported by all compilers. If your compiler supports member templates, you can call this function with any type of input iterator. If your compiler does not yet support member templates, though, then the arguments must either be of type const value_type* or of type hash_multimap::const_iterator.

See also

Associative Container, Hashed Associative Container, Pair Associative Container, Multiple Hashed Associative Container, set, map, multiset, multimap, hash_set, hash_map, hash_multiset


hash_multiset<Key, HashFcn, EqualKey, Alloc>

Category: containers | Component type: type

Description

Hash_multiset is a Hashed Associative Container that stores objects of type Key. Hash_multiset is a simple associative container, meaning that its value type, as well as its key type, is Key. It is also a Multiple Associative Container, meaning that two or more elements may compare equal using the Binary Predicate EqualKey.

Hash_multiset is useful in applications where it is important to be able to search for an element quickly. If it is important for the elements to be in a particular order, however, then multiset is more appropriate.

Example

struct eqstr
{
  bool operator()(const char* s1, const char* s2) const
  {
    return strcmp(s1, s2) == 0;
  }
};

void lookup(const hash_multiset<const char*, hash<const char*>, eqstr>& Set,
            const char* word)
{
  int n_found = Set.count(word);
  cout << word << ": "
       << n_found << " "
       << (n_found == 1 ? "instance" : "instances")
       << endl;
}

int main()
{
  hash_multiset<const char*, hash<const char*>, eqstr> Set;
  Set.insert("mango");
  Set.insert("kiwi");
  Set.insert("apple");
  Set.insert("kiwi");
  Set.insert("mango");
  Set.insert("mango");
  Set.insert("apricot");
  Set.insert("banana");
  Set.insert("mango");

  lookup(Set, "mango");
  lookup(Set, "apple");
  lookup(Set, "durian");
}

Definition

Defined in the header hash_set, and in the backward-compatibility header hash_set.h. This class is an SGI extension; it is not part of the C++ standard.

Template parameters

Parameter | Description | Default
Key | The hash_multiset's key type and value type. This is also defined as hash_multiset::key_type and hash_multiset::value_type |
HashFcn | The Hash Function used by the hash_multiset. This is also defined as hash_multiset::hasher. | hash<Key>
EqualKey | The hash_multiset's key equality function: a binary predicate that determines whether two keys are equal. This is also defined as hash_multiset::key_equal. | equal_to<Key>
Alloc | The hash_multiset's allocator, used for all internal memory management. | alloc

Model of

Multiple Hashed Associative Container, Simple Associative Container

Type requirements

  • Key is assignable.
  • EqualKey is a Binary Predicate whose argument type is Key.
  • EqualKey is an equivalence relation.
  • Alloc is an Allocator.

Public base classes

None.

Members

Member | Where defined | Description
value_type | Container | The type of object, T, stored in the hash_multiset.
key_type | Associative Container | The key type associated with value_type.
hasher | Hashed Associative Container | The hash_multiset's Hash Function.
key_equal | Hashed Associative Container | Function object that compares keys for equality.
pointer | Container | Pointer to T.
reference | Container | Reference to T
const_reference | Container | Const reference to T
size_type | Container | An unsigned integral type.
difference_type | Container | A signed integral type.
iterator | Container | Iterator used to iterate through a hash_multiset.
const_iterator | Container | Const iterator used to iterate through a hash_multiset. (Iterator and const_iterator are the same type.)
iterator begin() const | Container | Returns an iterator pointing to the beginning of the hash_multiset.
iterator end() const | Container | Returns an iterator pointing to the end of the hash_multiset.
size_type size() const | Container | Returns the size of the hash_multiset.
size_type max_size() const | Container | Returns the largest possible size of the hash_multiset.
bool empty() const | Container | true if the hash_multiset's size is 0.
size_type bucket_count() const | Hashed Associative Container | Returns the number of buckets used by the hash_multiset.
void resize(size_type n) | Hashed Associative Container | Increases the bucket count to at least n.
hasher hash_funct() const | Hashed Associative Container | Returns the hasher object used by the hash_multiset.
key_equal key_eq() const | Hashed Associative Container | Returns the key_equal object used by the hash_multiset.
hash_multiset() | Container | Creates an empty hash_multiset.
hash_multiset(size_type n) | Hashed Associative Container | Creates an empty hash_multiset with at least n buckets.
hash_multiset(size_type n,
              const hasher& h)
Hashed Associative Container Creates an empty hash_multiset with at least n buckets, using h as the hash function.
hash_multiset(size_type n,
              const hasher& h,
              const key_equal& k)
Hashed Associative Container Creates an empty hash_multiset with at least n buckets, using h as the hash function and k as the key equal function.
template <class InputIterator>
hash_multiset(InputIterator, InputIterator)
[1]
Multiple Hashed Associative Container Creates a hash_multiset with a copy of a range.
template <class InputIterator>
hash_multiset(InputIterator, InputIterator,
              size_type n)
[1]
Multiple Hashed Associative Container Creates a hash_multiset with a copy of a range and a bucket count of at least n.
template <class InputIterator>
hash_multiset(InputIterator, InputIterator,
              size_type n, const hasher& h)
[1]
Multiple Hashed Associative Container Creates a hash_multiset with a copy of a range and a bucket count of at least n, using h as the hash function.
template <class InputIterator>
hash_multiset(InputIterator, InputIterator,
              size_type n, const hasher& h,
              const key_equal& k)
[1]
Multiple Hashed Associative Container Creates a hash_multiset with a copy of a range and a bucket count of at least n, using h as the hash function and k as the key equal function.
hash_multiset(const hash_multiset&) | Container | The copy constructor.
hash_multiset& operator=(const hash_multiset&) | Container | The assignment operator
void swap(hash_multiset&) | Container | Swaps the contents of two hash_multisets.
iterator insert(const value_type& x) | Multiple Associative Container | Inserts x into the hash_multiset.
template <class InputIterator>
void insert(InputIterator, InputIterator)
[1]
Multiple Associative Container Inserts a range into the hash_multiset.
void erase(iterator pos) | Associative Container | Erases the element pointed to by pos.
size_type erase(const key_type& k) | Associative Container | Erases the element whose key is k.
void erase(iterator first, iterator last) | Associative Container | Erases all elements in a range.
void clear() | Associative Container | Erases all of the elements.
iterator find(const key_type& k) const | Associative Container | Finds an element whose key is k.
size_type count(const key_type& k) const | Associative Container | Counts the number of elements whose key is k.
pair<iterator, iterator>
equal_range(const key_type& k) const
Associative Container Finds a range containing all elements whose key is k.
bool operator==(const hash_multiset&,
                const hash_multiset&)
Hashed Associative Container Tests two hash_multisets for equality. This is a global function, not a member function.

New members

All of hash_multiset's members are defined in the Multiple Hashed Associative Container and Simple Associative Container requirements. Hash_multiset does not introduce any new members.

Notes

[1] This member function relies on member template functions, which at present (early 1998) are not supported by all compilers. If your compiler supports member templates, you can call this function with any type of input iterator. If your compiler does not yet support member templates, though, then the arguments must either be of type const value_type* or of type hash_multiset::const_iterator.

See also

Associative Container, Hashed Associative Container, Simple Associative Container, Multiple Hashed Associative Container, set, map, multiset, multimap, hash_set, hash_map, hash_multimap


hash_set<Key, HashFcn, EqualKey, Alloc>

Category: containers | Component type: type

Description

Hash_set is a Hashed Associative Container that stores objects of type Key. Hash_set is a Simple Associative Container, meaning that its value type, as well as its key type, is Key. It is also a Unique Associative Container, meaning that no two elements compare equal using the Binary Predicate EqualKey.

Hash_set is useful in applications where it is important to be able to search for an element quickly. If it is important for the elements to be in a particular order, however, then set is more appropriate.

Example

struct eqstr
{
  bool operator()(const char* s1, const char* s2) const
  {
    return strcmp(s1, s2) == 0;
  }
};

void lookup(const hash_set<const char*, hash<const char*>, eqstr>& Set,
            const char* word)
{
  hash_set<const char*, hash<const char*>, eqstr>::const_iterator it
    = Set.find(word);
  cout << word << ": "
       << (it != Set.end() ? "present" : "not present")
       << endl;
}

int main()
{
  hash_set<const char*, hash<const char*>, eqstr> Set;
  Set.insert("kiwi");
  Set.insert("plum");
  Set.insert("apple");
  Set.insert("mango");
  Set.insert("apricot");
  Set.insert("banana");

  lookup(Set, "mango");
  lookup(Set, "apple");
  lookup(Set, "durian");
}

Definition

Defined in the header hash_set, and in the backward-compatibility header hash_set.h. This class is an SGI extension; it is not part of the C++ standard.

Template parameters

Parameter | Description | Default
Key | The hash_set's key type and value type. This is also defined as hash_set::key_type and hash_set::value_type |
HashFcn | The Hash Function used by the hash_set. This is also defined as hash_set::hasher. | hash<Key>
EqualKey | The hash_set's key equality function: a binary predicate that determines whether two keys are equal. This is also defined as hash_set::key_equal. | equal_to<Key>
Alloc | The hash_set's allocator, used for all internal memory management. | alloc

Model of

Unique Hashed Associative Container, Simple Associative Container

Type requirements

  • Key is Assignable.
  • EqualKey is a Binary Predicate whose argument type is Key.
  • EqualKey is an equivalence relation.
  • Alloc is an Allocator.

Public base classes

None.

Members

Member | Where defined | Description
value_type | Container | The type of object, T, stored in the hash_set.
key_type | Associative Container | The key type associated with value_type.
hasher | Hashed Associative Container | The hash_set's Hash Function.
key_equal | Hashed Associative Container | Function object that compares keys for equality.
pointer | Container | Pointer to T.
reference | Container | Reference to T
const_reference | Container | Const reference to T
size_type | Container | An unsigned integral type.
difference_type | Container | A signed integral type.
iterator | Container | Iterator used to iterate through a hash_set.
const_iterator | Container | Const iterator used to iterate through a hash_set. (Iterator and const_iterator are the same type.)
iterator begin() const | Container | Returns an iterator pointing to the beginning of the hash_set.
iterator end() const | Container | Returns an iterator pointing to the end of the hash_set.
size_type size() const | Container | Returns the size of the hash_set.
size_type max_size() const | Container | Returns the largest possible size of the hash_set.
bool empty() const | Container | true if the hash_set's size is 0.
size_type bucket_count() const | Hashed Associative Container | Returns the number of buckets used by the hash_set.
void resize(size_type n) | Hashed Associative Container | Increases the bucket count to at least n.
hasher hash_funct() const | Hashed Associative Container | Returns the hasher object used by the hash_set.
key_equal key_eq() const | Hashed Associative Container | Returns the key_equal object used by the hash_set.
hash_set() | Container | Creates an empty hash_set.
hash_set(size_type n) | Hashed Associative Container | Creates an empty hash_set with at least n buckets.
hash_set(size_type n,
         const hasher& h)
Hashed Associative Container Creates an empty hash_set with at least n buckets, using h as the hash function.
hash_set(size_type n,
         const hasher& h,
         const key_equal& k)
Hashed Associative Container Creates an empty hash_set with at least n buckets, using h as the hash function and k as the key equal function.
template <class InputIterator>
hash_set(InputIterator f, InputIterator l)
[1]
Unique Hashed Associative Container Creates a hash_set with a copy of a range.
template <class InputIterator>
hash_set(InputIterator f, InputIterator l,
         size_type n)
[1]
Unique Hashed Associative Container Creates a hash_set with a copy of a range and a bucket count of at least n.
template <class InputIterator>
hash_set(InputIterator f, InputIterator l,
         size_type n, const hasher& h)
[1]
Unique Hashed Associative Container Creates a hash_set with a copy of a range and a bucket count of at least n, using h as the hash function.
hash_set(InputIterator f, InputIterator l,
         size_type n, const hasher& h,
         const key_equal& k)
[1]
Unique Hashed Associative Container Creates a hash_set with a copy of a range and a bucket count of at least n, using h as the hash function and k as the key equal function.
hash_set(const hash_set&) | Container | The copy constructor.
hash_set& operator=(const hash_set&) | Container | The assignment operator
void swap(hash_set&) | Container | Swaps the contents of two hash_sets.
pair<iterator, bool>
insert(const value_type& x)
Unique Associative Container Inserts x into the hash_set.
template <class InputIterator>
void insert(InputIterator f, InputIterator l)
[1]
Unique Associative Container Inserts a range into the hash_set.
void erase(iterator pos) | Associative Container | Erases the element pointed to by pos.
size_type erase(const key_type& k) | Associative Container | Erases the element whose key is k.
void erase(iterator first, iterator last) | Associative Container | Erases all elements in a range.
void clear() | Associative Container | Erases all of the elements.
iterator find(const key_type& k) const | Associative Container | Finds an element whose key is k.
size_type count(const key_type& k) const | Unique Associative Container | Counts the number of elements whose key is k.
pair<iterator, iterator>
equal_range(const key_type& k) const
Associative Container Finds a range containing all elements whose key is k.
bool operator==(const hash_set&,
                const hash_set&)
Hashed Associative Container Tests two hash_sets for equality. This is a global function, not a member function.

New members

All of hash_set's members are defined in the Unique Hashed Associative Container and Simple Associative Container requirements. Hash_set does not introduce any new members.

Notes

[1] This member function relies on member template functions, which at present (early 1998) are not supported by all compilers. If your compiler supports member templates, you can call this function with any type of input iterator. If your compiler does not yet support member templates, though, then the arguments must either be of type const value_type* or of type hash_set::const_iterator.

See also

Associative Container, Hashed Associative Container, Simple Associative Container, Unique Hashed Associative Container, set, map, multiset, multimap, hash_map, hash_multiset, hash_multimap


identity<T>

Category: functors | Component type: type

Description

Identity is a Unary Function that represents the identity function: it takes a single argument x, and returns x.

Example

int main()
{
  int x = 137;
  identity<int> id;
  assert(x == id(x));
}

Definition

Defined in the standard header functional, and in the nonstandard backward-compatibility header function.h. This class is an SGI extension; it is not part of the C++ standard.

Template parameters

Parameter | Description | Default
T | The function object's argument type, and return type. [1] |

Model of

Adaptable Unary Function

Type requirements

None.

Public base classes

unary_function<T, T>

Members

Member | Where defined | Description
argument_type | Adaptable Unary Function | The type of identity's argument: T.
result_type | Adaptable Unary Function | The type of the result: T. [1]
const T& operator()(const T&) const | Adaptable Unary Function | Function call. The return value is simply the argument.

New members

All of identity's members are defined in the Adaptable Unary Function requirements. Identity does not introduce any new members.

Notes

[1] It is essential that the return type and the argument type are the same: generalizing identity to allow them to differ would not work. The reason is that identity returns a const reference to its argument, rather than a copy of its argument. If identity were allowed to perform a conversion, then this would be a dangling reference.

See also

The function object overview, select1st, select2nd, project1st, project2nd


includes

Category: algorithms | Component type: function

Prototype

Includes is an overloaded name; there are actually two includes functions.
template <class InputIterator1, class InputIterator2>
bool includes(InputIterator1 first1, InputIterator1 last1,
              InputIterator2 first2, InputIterator2 last2);

template <class InputIterator1, class InputIterator2, class StrictWeakOrdering>
bool includes(InputIterator1 first1, InputIterator1 last1,
              InputIterator2 first2, InputIterator2 last2,
              StrictWeakOrdering comp);

Description

Includes tests whether one sorted range includes another sorted range. That is, it returns true if and only if, for every element in [first2, last2), an equivalent element [1] is also present in [first1, last1) [2]. Both [first1, last1) and [first2, last2) must be sorted in ascending order.

The two versions of includes differ in how they define whether one element is less than another. The first version compares objects using operator<, and the second compares objects using the function object comp.

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

For the first version:
  • InputIterator1 is a model of Input Iterator.
  • InputIterator2 is a model of Input Iterator.
  • InputIterator1 and InputIterator2 have the same value type.
  • InputIterator's value type is a model of LessThan Comparable.
  • The ordering on objects of InputIterator1's value type is a strict weak ordering, as defined in the LessThan Comparable requirements.
For the second version:
  • InputIterator1 is a model of Input Iterator.
  • InputIterator2 is a model of Input Iterator.
  • InputIterator1 and InputIterator2 have the same value type.
  • StrictWeakOrdering is a model of Strict Weak Ordering.
  • InputIterator1's value type is convertible to StrictWeakOrdering's argument type.

Preconditions

For the first version:
  • [first1, last1) is a valid range.
  • [first2, last2) is a valid range.
  • [first1, last1) is ordered in ascending order according to operator<. That is, for every pair of iterators i and j in [first1, last1) such that i precedes j, *j < *i is false.
  • [first2, last2) is ordered in ascending order according to operator<. That is, for every pair of iterators i and j in [first2, last2) such that i precedes j, *j < *i is false.
For the second version:
  • [first1, last1) is a valid range.
  • [first2, last2) is a valid range.
  • [first1, last1) is ordered in ascending order according to comp. That is, for every pair of iterators i and j in [first1, last1) such that i precedes j, comp(*j, *i) is false.
  • [first2, last2) is ordered in ascending order according to comp. That is, for every pair of iterators i and j in [first2, last2) such that i precedes j, comp(*j, *i) is false.

Complexity

Linear. Zero comparisons if either [first1, last1) or [first2, last2) is an empty range, otherwise at most 2 * ((last1 - first1) + (last2 - first2)) - 1 comparisons.

Example

int A1[] = { 1, 2, 3, 4, 5, 6, 7 };
int A2[] = { 1, 4, 7 };
int A3[] = { 2, 7, 9 };
int A4[] = { 1, 1, 2, 3, 5, 8, 13, 21 };
int A5[] = { 1, 2, 13, 13 };
int A6[] = { 1, 1, 3, 21 };

const int N1 = sizeof(A1) / sizeof(int);
const int N2 = sizeof(A2) / sizeof(int);
const int N3 = sizeof(A3) / sizeof(int);
const int N4 = sizeof(A4) / sizeof(int);
const int N5 = sizeof(A5) / sizeof(int);
const int N6 = sizeof(A6) / sizeof(int);

cout << "A2 contained in A1: "
     << (includes(A1, A1 + N1, A2, A2 + N2) ? "true" : "false") << endl;
cout << "A3 contained in A1: "
     << (includes(A1, A1 + N2, A3, A3 + N3) ? "true" : "false") << endl;
cout << "A5 contained in A4: "
     << (includes(A4, A4 + N4, A5, A5 + N5) ? "true" : "false") << endl;
cout << "A6 contained in A4: "
     << (includes(A4, A4 + N4, A6, A6 + N6) ? "true" : "false") << endl;
The output is:
A2 contained in A1: true
A3 contained in A1: false
A5 contained in A4: false
A6 contained in A4: true

Notes

[1] This reads "an equivalent element" rather than "the same element" because the ordering by which the input ranges are sorted is permitted to be a strict weak ordering that is not a total ordering: there might be values x and y that are equivalent (that is, neither x < y nor y < x is true) but not equal. See the LessThan Comparable requirements for a fuller discussion.) If you're using a total ordering (if you're using strcmp, for example, or if you're using ordinary arithmetic comparison on integers), then you can ignore this technical distinction: for a total ordering, equality and equivalence are the same.

[2] Note that the range [first2, last2) may contain a consecutive range of equivalent elements: there is no requirement that every element in the range be unique. In this case, includes will return false unless, for every element in [first2, last2), a distinct equivalent element is also present in [first1, last1). That is, if a certain value appears n times in [first2, last2) and m times in [first1, last1), then includes will return false if m < n.

See also

set_union, set_intersection, set_difference, set_symmetric_difference, sort


Standard Template Library Programmer's Guide

Introduction to the STL | How to use this site
Table of Contents | Download the STL
Index | Index by Category
Design Documents | What's New
Other STL Resources | Frequently Asked Questions
IOstreams library (experimental)
Send us a comment

Copyright © 1996-1999
Silicon Graphics Computer Systems, Inc.

Permission to use, copy, modify, distribute and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appears in all copies and that both that copyright notice and this permission notice appear in supporting documentation. Silicon Graphics makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty.

Copyright © 1994
Hewlett-Packard Company

Permission to use, copy, modify, distribute and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appears in all copies and that both that copyright notice and this permission notice appear in supporting documentation. Hewlett-Packard Company makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty.


inner_product

Category: algorithms | Component type: function

Prototype

Inner_product is an overloaded name; there are actually two inner_product functions.
template <class InputIterator1, class InputIterator2, class T>
T inner_product(InputIterator1 first1, InputIterator1 last1,
                InputIterator2 first2, T init);

template <class InputIterator1, class InputIterator2, class T,
          class BinaryFunction1, class BinaryFunction2>
T inner_product(InputIterator1 first1, InputIterator1 last1,
                InputIterator2 first2, T init, BinaryFunction1 binary_op1,
                BinaryFunction2 binary_op2);

Description

Inner_product calculates a generalized inner product of the ranges [first1, last1) and [first2, last2).

The first version of inner_product returns init plus the inner product of the two ranges [1]. That is, it first initializes the result to init and then, for each iterator i in [first1, last1), in order from the beginning to the end of the range, updates the result by result = result + (*i) * *(first2 + (i - first1)).

The second version of inner_product is identical to the first, except that it uses two user-supplied function objects instead of operator+ and operator*. That is, it first initializes the result to init and then, for each iterator i in [first1, last1), in order from the beginning to the end of the range, updates the result by result = binary_op1(result, binary_op2(*i, *(first2 + (i - first1))). [2]

Definition

Defined in the standard header numeric, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

For the first version:
  • InputIterator1 is a model of Input Iterator.
  • InputIterator2 is a model of Input Iterator.
  • T is a model of Assignable.
  • If x is an object of type T, y is an object of InputIterator1's value type, and z is an object of InputIterator2's value type, then x + y * z is defined.
  • The type of x + y * z is convertible to T.
For the second version:
  • InputIterator1 is a model of Input Iterator.
  • InputIterator2 is a model of Input Iterator.
  • T is a model of Assignable.
  • BinaryFunction1 is a model of Binary Function.
  • BinaryFunction2 is a model of Binary Function.
  • InputIterator1's value type is convertible to BinaryFunction2's first argument type.
  • InputIterator2's value type is convertible to BinaryFunction2's second argument type.
  • T is convertible to BinaryFunction1's first argument type.
  • BinaryFunction2's return type is convertible to BinaryFunction1's second argument type.
  • BinaryFunction1's return type is convertible to T.

Preconditions

  • [first1, last1) is a valid range.
  • [first2, first2 + (last1 - first1)) is a valid range.

Complexity

Linear. Exactly last1 - first1 applications of each binary operation.

Example

int main()
{
  int A1[] = {1, 2, 3};
  int A2[] = {4, 1, -2};
  const int N1 = sizeof(A1) / sizeof(int);

  cout << "The inner product of A1 and A2 is "
       << inner_product(A1, A1 + N1, A2, 0)
       << endl;
}

Notes

[1] There are several reasons why it is important that inner_product starts with the value init. One of the most basic is that this allows inner_product to have a well-defined result even if [first1, last1) is an empty range: if it is empty, the return value is init. The ordinary inner product corresponds to setting init to 0.

[2] Neither binary operation is required to be either associative or commutative: the order of all operations is specified.

See also

accumulate, partial_sum, adjacent_difference, count


inplace_merge

Category: algorithms | Component type: function

Prototype

Inplace_merge is an overloaded name: there are actually two inplace_merge functions.
template <class BidirectionalIterator>
inline void inplace_merge(BidirectionalIterator first,
                          BidirectionalIterator middle,
                          BidirectionalIterator last);

template <class BidirectionalIterator, class StrictWeakOrdering>
inline void inplace_merge(BidirectionalIterator first,
                          BidirectionalIterator middle,
                          BidirectionalIterator last, StrictWeakOrdering comp);

Description

Inplace_merge combines two consecutive sorted ranges [first, middle) and [middle, last) into a single sorted range [first, last). That is, it starts with a range [first, last) that consists of two pieces each of which is in ascending order, and rearranges it so that the entire range is in ascending order. Inplace_merge is stable, meaning both that the relative order of elements within each input range is preserved, and that for equivalent [1] elements in both input ranges the element from the first range precedes the element from the second.

The two versions of inplace_merge differ in how elements are compared. The first version uses operator<. That is, the input ranges and the output range satisfy the condition that for every pair of iterators i and j such that i precedes j, *j < *i is false. The second version uses the function object comp. That is, the input ranges and the output range satisfy the condition that for every pair of iterators i and j such that i precedes j, comp(*j, *i) is false.

Definition

Defined in algo.h.

Requirements on types

For the first version:
  • BidirectionalIterator is a model of Bidirectional Iterator.
  • BidirectionalIterator is mutable.
  • BidirectionalIterator's value type is a model of LessThan Comparable.
  • The ordering on objects of BidirectionalIterator's value type is a strict weak ordering, as defined in the LessThan Comparable requirements.
For the second version:
  • BidirectionalIterator is a model of Bidirectional Iterator.
  • BidirectionalIterator is mutable.
  • StrictWeakOrdering is a model of Strict Weak Ordering.
  • BidirectionalIterator's value type is convertible to StrictWeakOrdering's argument type.

Preconditions

For the first version:
  • [first, middle) is a valid range.
  • [middle, last) is a valid range.
  • [first, middle) is in ascending order. That is, for every pair of iterators i and j in [first, middle) such that i precedes j, *j < *i is false.
  • [middle, last) is in ascending order. That is, for every pair of iterators i and j in [middle, last) such that i precedes j, *j < *i is false.
For the second version:
  • [first, middle) is a valid range.
  • [middle, last) is a valid range.
  • [first, middle) is in ascending order. That is, for every pair of iterators i and j in [first, middle) such that i precedes j, comp(*j, *i) is false.
  • [middle, last) is in ascending order. That is, for every pair of iterators i and j in [middle, last) such that i precedes j, comp(*j, *i) is false.

Complexity

Inplace_merge is an adaptive algorithm: it attempts to allocate a temporary memory buffer, and its run-time complexity depends on how much memory is available. Inplace_merge performs no comparisons if [first, last) is an empty range. Otherwise, worst-case behavior (if no auxiliary memory is available) is O(N log(N)), where N is last - first, and best case (if a large enough auxiliary memory buffer is available) is at most (last - first) - 1 comparisons.

Example

int main()
{
  int A[] = { 1, 3, 5, 7, 2, 4, 6, 8 };

  inplace_merge(A, A + 4, A + 8);
  copy(A, A + 8, ostream_iterator<int>(cout, " "));
  // The output is "1 2 3 4 5 6 7 8".
}

Notes

[1] Note that you may use an ordering that is a strict weak ordering but not a total ordering; that is, there might be values x and y such that x < y, x > y, and x == y are all false. (See the LessThan Comparable requirements for a fuller discussion.) Two elements x and y are equivalent if neither x < y nor y < x. If you're using a total ordering, however (if you're using strcmp, for example, or if you're using ordinary arithmetic comparison on integers), then you can ignore this technical distinction: for a total ordering, equality and equivalence are the same.

See also

merge, set_union, sort


Input Iterator

Category: iterators | Component type: concept

Description

An Input Iterator is an iterator that may be dereferenced to refer to some object, and that may be incremented to obtain the next iterator in a sequence. Input Iterators are not required to be mutable.

Refinement of

Trivial iterator.

Associated types

Value type | The type of the value obtained by dereferencing an Input Iterator
Distance type | A signed integral type used to represent the distance from one iterator to another, or the number of elements in a range.

Notation

X | A type that is a model of Input Iterator
T | The value type of X
i, j | Object of type X
t | Object of type T

Definitions

An iterator is past-the-end if it points beyond the last element of a container. Past-the-end values are nonsingular and nondereferenceable.

An iterator is valid if it is dereferenceable or past-the-end.

An iterator i is incrementable if there is a "next" iterator, that is, if ++i is well-defined. Past-the-end iterators are not incrementable.

An Input Iterator j is reachable from an Input Iterator i if, after applying operator++ to i a finite number of times, i == j. [1]

The notation [i,j) refers to a range of iterators beginning with i and up to but not including j.

The range [i,j) is a valid range if both i and j are valid iterators, and j is reachable from i [2].

Valid expressions

In addition to the expressions defined in Trivial Iterator, the following expressions must be valid.
Name | Expression | Type requirements | Return type
Preincrement | ++i |  | X&
Postincrement | (void)i++ |  |
Postincrement and dereference | *i++ |  | T

Expression semantics

Name | Expression | Precondition | Semantics | Postcondition
Dereference | *t | i is incrementable |  |
Preincrement | ++i | i is dereferenceable |  | i is dereferenceable or past-the-end [3] [4]
Postincrement | (void)i++ | i is dereferenceable | Equivalent to (void)++i | i is dereferenceable or past-the-end [3] [4]
Postincrement and dereference | *i++ | i is dereferenceable | Equivalent to {T t = *i; ++i; return t;} | i is dereferenceable or past-the-end [3] [4]

Complexity guarantees

All operations are amortized constant time.

Invariants

Models

  • istream_iterator

Notes

[1] i == j does not imply ++i == ++j.

[2] Every iterator in a valid range [i, j) is dereferenceable, and j is either dereferenceable or past-the-end. The fact that every iterator in the range is dereferenceable follows from the fact that incrementable iterators must be deferenceable.

[3] After executing ++i, it is not required that copies of the old value of i be dereferenceable or that they be in the domain of operator==.

[4] It is not guaranteed that it is possible to pass through the same input iterator twice.

See also

Output Iterator, Iterator overview


input_iterator<T, Distance>

Category: iterators | Component type: type

Description

Input_iterator is an iterator base class: it is intended that an iterator that is a model of Input Iterator, and whose value type and distance type are T and Distance, may be defined by inheriting from input_iterator<T, Distance> [1]. Input_iterator is entirely empty: it has no member functions, member variables, or nested types. It exists solely to simplify the definition of the functions iterator_category, distance_type, and value_type.

Example

class my_input_iterator : public input_iterator<double>
{
  ...
};
This declares my_input_iterator to be an Input Iterator whose value type is double and whose distance type is ptrdiff_t. If Iter is an object of class my_input_iterator, then iterator_category(Iter) will return input_iterator_tag(), value_type(Iter) will return (double*) 0, and distance_type(Iter) will return (ptrdiff_t*) 0.

Definition

Defined in the standard header iterator, and in the nonstandard backward-compatibility header iterator.h. This class is no longer part of the C++ standard, although it was present in early drafts of the standard. It is retained in this implementation for backward compatibility.

Template parameters

Parameter | Description | Default
T | The iterator's value type |
Distance | The iterator's distance type | ptrdiff_t

Model of

Assignable

Public base classes

None

Type requirements

The distance type must be a signed integral type.

Public base classes

None.

Members

None.

New Members

None.

Notes

[1] It is not required that an Input Iterator inherit from the base input_iterator. It is, however, required that the functions iterator_category, distance_type, and value_type be defined for every Input Iterator. (Or, if you are using the iterator_traits mechanism, that iterator_traits is properly specialized for every Input Iterator.) Since those functions are defined for the base input_iterator, the easiest way to ensure that are defined for a new iterator class is to derive that class from input_iterator and rely on the derived-to-base standard conversion of function arguments.

See also

The Iterator Tags overview, iterator_traits, iterator_category, value_type, distance_type, output_iterator, forward_iterator, bidirectional_iterator, random_access_iterator


input_iterator_tag

Category: iterators | Component type: type

Description

Input_iterator_tag is an empty class: it has no member functions, member variables, or nested types. It is used solely as a "tag": a representation of the Input Iterator concept within the C++ type system. Specifically, it is used as a return value for the function iterator_category. Iterator_category takes a single argument, an iterator, and returns an object whose type depends on the iterator's category. Iterator_category's return value is of type input_iterator_tag if its argument is an Input Iterator.

Example

See iterator_category

Definition

Defined in the standard header iterator, and in the nonstandard backward-compatibility header iterator.h.

Template parameters

None.

Model of

Assignable

Type requirements

None.

Public base classes

None.

Members

None.

New Members

None.

Notes

See also

iterator_category, Iterator Tags, iterator_traits, output_iterator_tag, forward_iterator_tag, bidirectional_iterator_tag, random_access_iterator_tag


insert_iterator<Container>

Categories: iterators, adaptors | Component type: type

Description

Insert_iterator is an iterator adaptor that functions as an Output Iterator: assignment through an insert_iterator inserts an object into a Container. Specifically, if ii is an insert_iterator, then ii keeps track of a Container c and an insertion point p; the expression *ii = x performs the insertion c.insert(p, x). [1]

There are two different Container concepts that define this expression: Sequence, and Sorted Associative Container. Both concepts define insertion into a container by means of c.insert(p, x), but the semantics of this expression is very different in the two cases.

For a Sequence S, the expression S.insert(p, x) means to insert the value x immediately before the iterator p. That is, the two-argument version of insert allows you to control the location at which the new element will be inserted. For a Sorted Associative Container, however, no such control is possible: the elements in a Sorted Associative Container always appear in ascending order of keys. Sorted Associative Containers define the two-argument version of insert as an optimization. The first argument is only a hint: it points to the location where the search will begin.

If you assign through an insert_iterator several times, then you will be inserting several elements into the underlying container. In the case of a Sequence, they will appear at a particular location in the underlying sequence, in the order in which they were inserted: one of the arguments to insert_iterator's constructor is an iterator p, and the new range will be inserted immediately before p.

In the case of a Sorted Associative Container, however, the iterator in the insert_iterator's constructor is almost irrelevant. The new elements will not necessarily form a contiguous range; they will appear in the appropriate location in the container, in ascending order by key. The order in which they are inserted only affects efficiency: inserting an already-sorted range into a Sorted Associative Container is an O(N) operation.

Example

Insert a range of elements into a list.
list<int> L;
L.push_front(3);
insert_iterator<list<int> > ii(L, L.begin());
*ii++ = 0;
*ii++ = 1;
*ii++ = 2;
copy(L.begin(), L.end(), ostream_iterator<int>(cout, " "));
// The values that are printed are 0 1 2 3.
Merge two sorted lists, inserting the resulting range into a set. Note that a set never contains duplicate elements.
int main()
{
  const int N = 6;

  int A1[N] = {1, 3, 5, 7, 9, 11};
  int A2[N] = {1, 2, 3, 4, 5, 6};
  set<int> result;

  merge(A1, A1 + N, A2, A2 + N,
        inserter(result, result.begin()));

  copy(result.begin(), result.end(), ostream_iterator<int>(cout, " "));
  cout << endl;

  // The output is "1 2 3 4 5 6 7 9 11".
}

Definition

Defined in the standard header iterator, and in the nonstandard backward-compatibility header iterator.h.

Template parameters

Parameter | Description | Default
Container | The type of Container into which values will be inserted. |

Model of

Output Iterator. An insert iterator's set of value types (as defined in the Output Iterator requirements) consists of a single type: Container::value_type.

Type requirements

  • The template parameter Container is a model of Container.
  • Container is variable-sized, as described in the Container requirements.
  • Container has a two-argument insert member function. Specifically, if c is an object of type Container, p is an object of type Container::iterator and v is an object of type Container::value_type, then c.insert(p, v) must be a valid expression.

Public base classes

None.

Members

Member | Where defined | Description
insert_iterator(Container&, Container::iterator) | insert_iterator | See below.
insert_iterator(const insert_iterator&) | Trivial Iterator | The copy constructor
insert_iterator& operator=(const insert_iterator&) | Trivial Iterator | The assignment operator
insert_iterator& operator*() | Output Iterator | Used to implement the output iterator expression *i = x. [2]
insert_iterator& operator=(const Container::value_type&) | Output Iterator | Used to implement the output iterator expression *i = x. [2]
insert_iterator& operator++() | Output Iterator | Preincrement.
insert_iterator& operator++(int) | Output Iterator | Postincrement.
output_iterator_tag iterator_category(const insert_iterator&) | iterator tags | Returns the iterator's category. This is a global function, not a member.
template<class Container, class Iter)
insert_iterator<Container>
inserter(Container& C, Iter i);
insert_iterator See below.

New members

These members are not defined in the Output Iterator requirements, but are specific to insert_iterator.
Member | Description
insert_iterator(Container& C, Container::iterator i) | Constructs an insert_iterator that inserts objects in C. If Container is a Sequence, then each object will be inserted immediately before the element pointed to by i. If C is a Sorted Associative Container, then the first insertion will use i as a hint for beginning the search. The iterator i must be a dereferenceable or past-the-end iterator in C.
template<class Container, class Iter)
insert_iterator<Container>
inserter(Container& C, Iter i);
Equivalent to insert_iterator<Container>(C, i). [2] This is a global function, not a member function.

Notes

[1] Note the difference between assignment through a Container::iterator and assignment through an insert_iterator<Container>. If i is a valid Sequence::iterator, then it points to some particular element in the container; the expression *i = t replaces that element with t, and does not change the total number of elements in the container. If ii is a valid insert_iterator<container>, however, then the expression *ii = t is equivalent, for some container c and some valid container::iterator j, to the expression c.insert(j, t). That is, it does not overwrite any of c's elements and it does change c's size.

[2] Note how assignment through an insert_iterator is implemented. In general, unary operator* must be defined so that it returns a proxy object, where the proxy object defines operator= to perform the insert operation. In this case, for the sake of simplicity, the proxy object is the insert_iterator itself. That is, *i simply returns i, and *i = t is equivalent to i = t. You should not, however, rely on this behavior. It is an implementation detail, and it is not guaranteed to remain the same in future versions.

[3] This function exists solely for the sake of convenience: since it is a non-member function, the template parameters may be inferred and the type of the insert_iterator need not be declared explicitly. One easy way to reverse a range and insert it into a Sequence S, for example, is reverse_copy(first, last, inserter(S, S.begin())).

See also

front_insert_iterator, back_insert_iterator, Output Iterator, Sequence, Iterator overview


iota

Category: algorithms | Component type: function

Prototype

template <class ForwardIterator, class T>
void iota(ForwardIterator first, ForwardIterator last, T value);

Description

Iota assigns sequentially increasing values to a range. That is, it assigns value to *first, value + 1 to *(first + 1) and so on. In general, each iterator i in the range [first, last) is assigned value + (i - first). [1]

Definition

Defined in the standard header numeric, and in the nonstandard backward-compatibility header algo.h. This function is an SGI extension; it is not part of the C++ standard.

Requirements on types

  • ForwardIterator is a model of Forward Iterator.
  • ForwardIterator is mutable.
  • T is Assignable.
  • If x is an object of type T, then x++ is defined.
  • T is convertible to ForwardIterator's value type.

Preconditions

  • [first, last) is a valid range.

Complexity

Linear. Exactly last - first assignments.

Example

int main()
{
  vector<int> V(10);

  iota(V.begin(), V.end(), 7);
  copy(V.begin(), V.end(), ostream_iterator<int>(cout, " "));
  cout << endl;
}

Notes

[1] The name iota is taken from the programming language APL.

See also

fill, generate, partial_sum


istream_iterator<T, Distance>

Category: iterators | Component type: type

Description

An istream_iterator is an Input Iterator that performs formatted input of objects of type T from a particular istream. When end of stream is reached, the istream_iterator takes on a special end of stream value, which is a past-the-end iterator. Note that all of the restrictions of an Input Iterator must be obeyed, including the restrictions on the ordering of operator* and operator++ operations.

Example

Fill a vector with values read from standard input.
vector<int> V;
copy(istream_iterator<int>(cin), istream_iterator<int>(),
     back_inserter(V));

Definition

Defined in the standard header iterator, and in the nonstandard backward-compatibility header iterator.h.

Template parameters

Parameter | Description | Default
T | The istream_iterator's value type. Operator* returns a const T&. |
Distance | The istream_iterator's distance type. | ptrdiff_t

Model of

Input Iterator

Type requirements

The value type T must be a type such that cin >> T is a valid expression.

The value type T must be a model of Default Constructible.

The distance type must, as described in the Input Iterator requirements, be a signed integral type.

Public base classes

None.

Members

Member | Where defined | Description
istream_iterator() | istream_iterator | See below.
istream_iterator(istream&) | istream_iterator | See below.
istream_iterator(const istream_iterator&) | Trivial Iterator | The copy constructor
istream_iterator& operator=(const istream_iterator&) | Trivial Iterator | The assignment operator
const T& operator*() const | Input Iterator | Returns the next object in the stream.
istream_iterator& operator++() | Input Iterator | Preincrement.
istream_iterator& operator++(int) | Input Iterator | Postincrement.
bool operator==(const istream_iterator&, const istream_iterator&) | Trivial iterator | The equality operator. This is a global function, not a member function.
input_iterator_tag iterator_category(const istream_iterator&) | iterator tags | Returns the iterator's category.
T* value_type(const istream_iterator&) | iterator tags | Returns the iterator's value type.
Distance* distance_type(const istream_iterator&) | iterator tags | Returns the iterator's distance type. <

New members

These members are not defined in the Input Iterator requirements, but are specific to istream_iterator.
Function | Description
istream_iterator() | The default constructor: Constructs an end-of-stream iterator. This is a past-the-end iterator, and it is useful when constructing a "range".
istream_iterator(istream& s) | Creates an istream_iterator that reads values from the input stream s. When s reaches end of stream, this iterator will compare equal to an end-of-stream iterator created using the default constructor.

Notes

See also

ostream_iterator, Input Iterator, Output Iterator.


is_heap

Category: algorithms | Component type: function

Prototype

Is_heap is an overloaded name; there are actually two is_heap functions.
template <class RandomAccessIterator>
bool is_heap(RandomAccessIterator first, RandomAccessIterator last);

template <class RandomAccessIterator, class StrictWeakOrdering>
inline bool is_heap(RandomAccessIterator first, RandomAccessIterator last,
                    StrictWeakOrdering comp)

Description

Is_heap returns true if the range [first, last) is a heap [1], and false otherwise. The two versions differ in how they define whether one element is less than another: the first version compares objects using operator<, and the second compares objects using a function object comp.

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h. This function is an SGI extension; it is not part of the C++ standard.

Requirements on types

For the first version:
  • RandomAccessIterator is a model of Random Access Iterator.
  • RandomAccessIterator's value type is a model of LessThan Comparable.
  • The ordering on objects of RandomAccessIterator's value type is a strict weak ordering, as defined in the LessThan Comparable requirements.
For the second version:
  • RandomAccessIterator is a model of Random Access Iterator.
  • StrictWeakOrdering is a model of Strict Weak Ordering.
  • RandomAccessIterator's value type is convertible to StrictWeakOrdering's argument type.

Preconditions

  • [first, last) is a valid range.

Complexity

Linear. Zero comparisons if [first, last) is an empty range, otherwise at most (last - first) - 1 comparisons.

Example

int A[] = {1, 2, 3, 4, 5, 6, 7};
const int N = sizeof(A) / sizeof(int);

assert(!is_heap(A, A+N));
make_heap(A, A+N);
assert(is_heap(A, A+N));

Notes

[1] A heap is a particular way of ordering the elements in a range of Random Access Iterators [f, l). The reason heaps are useful (especially for sorting, or as priority queues) is that they satisfy two important properties. First, *f is the largest element in the heap. Second, it is possible to add an element to a heap (using push_heap), or to remove *f, in logarithmic time. Internally, a heap is a tree represented as a sequential range. The tree is constructed so that that each node is less than or equal to its parent node.

See also

make_heap, push_heap, pop_heap, sort_heap


is_sorted

Category: algorithms | Component type: function

Prototype

Is_sorted is an overloaded name; there are actually two is_sorted functions.
template <class ForwardIterator>
bool is_sorted(ForwardIterator first, ForwardIterator last)

template <class ForwardIterator, class StrictWeakOrdering>
bool is_sorted(ForwardIterator first, ForwardIterator last,
               StrictWeakOrdering comp)

Description

Is_sorted returns true if the range [first, last) is sorted in ascending order, and false otherwise.

The two versions of is_sorted differ in how they define whether one element is less than another. The first version compares objects using operator<, and the second compares objects using the function object comp. The first version of is_sorted returns true if and only if, for every iterator i in the range [first, last - 1), *(i + 1) < *i is false. The second version returns true if and only if, for every iterator i in the range [first, last - 1), comp(*(i + 1), *i) is false

Definition

Defined in algo.h.

Requirements on types

For the first version:
  • ForwardIterator is a model of Forward Iterator.
  • ForwardIterator's value type is a model of LessThan Comparable.
  • The ordering on objects of ForwardIterator's value type is a strict weak ordering, as defined in the LessThan Comparable requirements.
For the second version:
  • ForwardIterator is a model of Forward Iterator.
  • StrictWeakOrdering is a model of Strict Weak Ordering.
  • ForwardIterator's value type is convertible to StrictWeakOrdering's argument type.

Preconditions

  • [first, last) is a valid range.

Complexity

Linear. Zero comparisons if [first, last) is an empty range, otherwise at most (last - first) - 1 comparisons.

Example

int A[] = {1, 4, 2, 8, 5, 7};
const int N = sizeof(A) / sizeof(int);

assert(!is_sorted(A, A + N));
sort(A, A + N);
assert(is_sorted(A, A + N));

Notes

See also

sort, stable_sort, partial_sort, partial_sort_copy, sort_heap, binary_search, lower_bound, upper_bound, less<T>, StrictWeakOrdering, LessThan Comparable


Iterators

Category: iterators | Component type: overview

Summary

Iterators are a generalization of pointers: they are objects that point to other objects. As the name suggests, iterators are often used to iterate over a range of objects: if an iterator points to one element in a range, then it is possible to increment it so that it points to the next element.

Iterators are central to generic programming because they are an interface between containers and algorithms: algorithms typically take iterators as arguments, so a container need only provide a way to access its elements using iterators. This makes it possible to write a generic algorithm that operates on many different kinds of containers, even containers as different as a vector and a doubly linked list.

The STL defines several different concepts related to iterators, several predefined iterators, and a collection of types and functions for manipulating iterators.

Description

Iterators are in fact not a single concept, but six concepts that form a hierarchy: some of them define only a very restricted set of operations, while others define additional functionality. The five concepts that are actually used by algorithms are Input Iterator, Output Iterator, Forward Iterator, Bidirectional Iterator, and Random Access Iterator. A sixth concept, Trivial Iterator, is introduced only to clarify the definitions of the other iterator concepts.

The most restricted sorts of iterators are Input Iterators and Output Iterators, both of which permit "single pass" algorithms but do not necessarily support "multi-pass" algorithms. Input iterators only guarantee read access: it is possible to dereference an Input Iterator to obtain the value it points to, but not it is not necessarily possible to assign a new value through an input iterator. Similarly, Output Iterators only guarantee write access: it is possible to assign a value through an Output Iterator, but not necessarily possible to refer to that value.

Forward Iterators are a refinement of Input Iterators and Output Iterators: they support the Input Iterator and Output Iterator operations and also provide additional functionality. In particular, it is possible to use "multi-pass" algorithms with Forward Iterators. A Forward Iterator may be constant, in which case it is possible to access the object it points to but not to to assign a new value through it, or mutable, in which case it is possible to do both.

Bidirectional Iterators, like Forward Iterators, allow multi-pass algorithms. As the name suggests, they are different in that they support motion in both directions: a Bidirectional Iterator may be incremented to obtain the next element or decremented to obtain the previous element. A Forward Iterator, by contrast, is only required to support forward motion. An iterator used to traverse a singly linked list, for example, would be a Forward Iterator, while an iterator used to traverse a doubly linked list would be a Bidirectional Iterator.

Finally, Random Access Iterators allow the operations of pointer arithmetic: addition of arbitrary offsets, subscripting, subtraction of one iterator from another to find a distance, and so on.

Most algorithms are expressed not in terms of a single iterator but in terms of a range of iterators [1]; the notation [first, last) refers to all of the iterators from first up to, but not including, last. [2] Note that a range may be empty, i.e. first and last may be the same iterator. Note also that if there are n iterators in a range, then the notation [first, last) represents n+1 positions. This is crucial: algorithms that operate on n things frequently require n+1 positions. Linear search, for example (find) must be able to return some value to indicate that the search was unsuccessful.

Sometimes it is important to be able to infer some properties of an iterator: the type of object that is returned when it is dereferenced, for example. There are two different mechanisms to support this sort of inferrence: an older mechanism called Iterator Tags, and a newer mechanism called iterator_traits [3].

Concepts

  • Trivial Iterator
  • Input Iterator
  • Output Iterator
  • Forward Iterator
  • Bidirectional Iterator
  • Random Access Iterator

Types

  • istream_iterator
  • ostream_iterator
  • reverse_iterator
  • reverse_bidirectional_iterator
  • insert_iterator
  • front_insert_iterator
  • back_insert_iterator
  • iterator_traits
  • input_iterator_tag
  • output_iterator_tag
  • forward_iterator_tag
  • bidirectional_iterator_tag
  • random_access_iterator_tag
  • input_iterator
  • output_iterator
  • forward_iterator
  • bidirectional_iterator
  • random_access_iterator

Functions

  • distance_type
  • value_type
  • iterator_category
  • distance
  • advance
  • inserter
  • front_inserter
  • back_inserter

Notes

[1] Ranges are not a well-defined concept for Trivial Iterators, because a Trivial Iterator cannot be incremented: there is no such thing as a next element. They are also not a well-defined concept for Output Iterators, because it is impossible to compare two Output Iterators for equality. Equality is crucial to the definition of a range, because only by comparing an iterator for equality with the last element is it possible to step through a range.

[2] Sometimes the notation [first, last) refers to the iterators first, first+1, ..., last-1 and sometimes it refers to the objects pointed to by those iterators: *first, *(first+1), ..., *(last-1). In most cases it will be obvious from context which of these is meant; where the distinction is important, the notation will be qualified explicitly as "range of iterators" or "range of objects".

[3] The iterator_traits class relies on a C++ feature known as partial specialization. Many of today's compilers don't implement the complete standard; in particular, many compilers do not support partial specialization. If your compiler does not support partial specialization, then you will not be able to use iterator_traits, and you will instead have to continue using the functions iterator_category, distance_type, and value_type.

See also

[Silicon Surf] [STL Home]
Copyright © 1999 Silicon Graphics, Inc. All Rights Reserved. TrademarkInformation


iterator_category

Category: iterators | Component type: function

Prototype

Iterator_category is overloaded; it is in fact six different functions.
inline output_iterator_tag iterator_category(const output_iterator&);

template <class T, class Distance>
inline input_iterator_tag
iterator_category(const input_iterator<T, Distance>&);

template <class T, class Distance>
inline forward_iterator_tag
iterator_category(const forward_iterator<T, Distance>&);

template <class T, class Distance>
inline bidirectional_iterator_tag
iterator_category(const bidirectional_iterator<T, Distance>&);

template <class T, class Distance>
inline random_access_iterator_tag
iterator_category(const random_access_iterator<T, Distance>&);

template <class T>
inline random_access_iterator_tag iterator_category(const T*);

Description

Iterator_category is an iterator tag function: it is used to determine the category to which an iterator belongs. Specifically, every iterator must belong to a type that is a model of the concept Output Iterator, Input Iterator, Forward Iterator, Bidirectional Iterator, or Random Access Iterator. [1] Iterator_category returns an object of class output_iterator_tag, input_iterator_tag, forward_iterator_tag, or random_access_iterator_tag, depending on which concept the type of iterator_category's argument is a model of. [2] This information is useful in the case of an algorithm that has a sensible definition for more than one category of iterator, but whose definition is different depending on the category.

Although iterator_category looks like a single function whose return type depends on its argument type, in reality it is a set of functions; the name iterator_category is overloaded. The function iterator_category must be overloaded for every iterator type.

In practice, ensuring that iterator_category is defined requires essentially no work at all. It is already defined for pointers, and for the base classes input_iterator, output_iterator, forward_iterator, bidirectional_iterator, and random_access_iterator. If you are implementing a new type of forward iterator, for example, you can simply derive it from the base class forward_iterator; this means that iterator_category (along with distance_type and value_type) will automatically be defined for your iterator. These base classes are empty: they contain no member functions or member variables, but only type information. Using them should therefore incur no overhead.

Note that, while the function iterator_category was present in the original STL, it is no longer present in the most recent draft C++ standard: it has been replaced by the iterator_traits class. At present both mechanisms are supported [3], but eventually iterator_category will be removed.

Definition

Defined in the standard header iterator, and in the nonstandard backward-compatibility header iterator.h. This function is no longer part of the C++ standard, although it was present in early drafts of the standard. It is retained in this implementation for backward compatibility.

Requirements on types

The argument of iterator_category must be an iterator.

Preconditions

None. Iterator_category's argument is even permitted to be a singular iterator.

Complexity

At most amortized constant time. In many cases, a compiler should be able to optimize away iterator_category entirely.

Example

Reverse can be implemented for either Bidirectional Iterators or for Random Access Iterators, but the algorithm for Random Access Iterators is more efficient. Consequently, reverse uses iterator_category to select whichever algorithm is appropriate for the iterator type. This dispatch takes place at compile time, and should not incur any run-time penalty.
template <class BidirectionalIterator>
void __reverse(BidirectionalIterator first, BidirectionalIterator last,
               bidirectional_iterator_tag) {
    while (true)
        if (first == last || first == --last)
            return;
        else
            iter_swap(first++, last);
}

template <class RandomAccessIterator>
void __reverse(RandomAccessIterator first, RandomAccessIterator last,
               random_access_iterator_tag) {
    while (first < last) iter_swap(first++, --last);
}

template <class BidirectionalIterator>
inline void reverse(BidirectionalIterator first, BidirectionalIterator last) {
    __reverse(first, last, iterator_category(first));
}

Notes

[1] The STL also defines one other concept, Trivial Iterator. This concept is introduced only for conceptual clarity, however, in order to separate the axioms related to an object that refers to another object from those related to iteration over a range. In fact, the STL does not define any types that are Trivial Iterators. Although built-in C pointers may be Trivial Iterators, the C type system does not allow a distinction between pointers that are Trivial Iterators and pointers that are Random Access Iterators into C arrays. Consequently, there is no Trivial Iterator category tag.

[2] Any type that is a model of Forward Iterator is also a model of Input Iterator, any type that is a model of Bidirectional Iterator is also a model of Forward Iterator, and any type that is a model of Random Access Iterator is also a model of Bidirectional Iterator. Iterator_category must return a tag representing the most specific concept that its argument is a model of. If its argument is a vector::iterator, for example, then it must return random_access_iterator_tag.

[3] The iterator_traits class relies on a C++ feature known as partial specialization. Many of today's compilers don't implement the complete standard; in particular, many compilers do not support partial specialization. If your compiler does not support partial specialization, then you will not be able to use iterator_traits, and you will have to continue using the functions iterator_category, distance_type, and value_type. This is one reason that those functions have not yet been removed.

See also

The Iterator Tags overview, iterator_traits, distance_type, value_type, output_iterator_tag, input_iterator_tag, forward_iterator_tag, bidirectional_iterator_tag, random_access_iterator_tag


Iterator Tags

Category: iterators | Component type: overview

Summary

Iterator tag functions are a method for accessing information that is associated with iterators. Specifically, an iterator type must, as discussed in the Input Iterator requirements, have an associated distance type and value type. [1] It is sometimes important for an algorithm parameterized by an iterator type to be able to determine the distance type and value type. Iterator tags also allow algorithms to determine an iterator's category, so that they can take different actions depending on whether an iterator is an Input Iterator, Output Iterator, Forward Iterator, Bidirectional Iterator, or Random Access Iterator.

Note that the iterator tag functions distance_type, value_type, and iterator_category are an older method of accessing the type information associated with iterators: they were defined in the original STL. The draft C++ standard, however, defines a different and more convenient mechanism: iterator_traits. Both mechanisms are supported [2], for reasons of backwards compatibility, but the older mechanism will eventually be removed.

Description

The basic idea of the iterator tag functions, and of iterator_traits, is quite simple: iterators have associated type information, and there must be a way to access that information. Specifically, iterator tag functions and iterator_traits are used to determine an iterator's value type, distance type, and iterator category.

An iterator's category is the most specific concept that it is a model of: Input Iterator, Output Iterator, Forward Iterator, Bidirectional Iterator, or Random Access Iterator. This information is expressed in the C++ type system by defining five category tag types, input_iterator_tag, output_iterator_tag, forward_iterator_tag, bidirectional_iterator_tag, and random_access_iterator_tag, each of which corresponds to one of those concepts. [3]

The function iterator_category takes a single argument, an iterator, and returns the tag corresponding to that iterator's category. That is, it returns a random_access_iterator_tag if its argument is a pointer, a bidirectional_iterator_tag if its argument is a list::iterator, and so on. Iterator_traits provides the same information in a slightly different way: if I is an iterator, then iterator_traits<I>::iterator_category is a nested typedef: it is one of the five category tag types.

An iterator's value type is the type of object that is returned when the iterator is dereferenced. (See the discussion in the Input Iterator requirements.) Ideally, one might want value_type to take a single argument, an iterator, and return the iterator's value type. Unfortunately, that's impossible: a function must return an object, and types aren't objects. Instead, value_type returns the value (T*) 0, where T is the argument's value type. The iterator_traits class, however, does not have this restriction: iterator_traits<I>::value_type is a type, not a value. It is a nested typedef, and it can be used in declarations of variables, as an function's argument type or return type, and in any other ways that C++ types can be used.

(Note that the function value_type need not be defined for Output Iterators, since an Output Iterator need not have a value type. Similarly, iterator_traits<I>::value_type is typically defined as void when I is an output iterator)

An iterator's distance type, or difference type (the terms are synonymous) is the type that is used to represent the distance between two iterators. (See the discussion in the Input Iterator requirements.) The function distance_type returns this information in the same form that value_type does: its argument is an iterator, and it returns the value (Distance*) 0, where Distance is the iterator's distance type. Similarly, iterator_traits<I>::difference_type is I's distance type.

Just as with value_type, the function distance_type need not be defined for Output Iterators, and, if I is an Output Iterator, iterator_traits<I>::difference_type may be defined as void. An Output Iterator need not have a distance type.

The functions iterator_category, value_type, and distance_type must be provided for every type of iterator. (Except, as noted above, that value_type and distance_type need not be provided for Output Iterators.) In principle, this is simply a matter of overloading: anyone who defines a new iterator type must define those three functions for it. In practice, there's a slightly more convenient method. The STL defines five base classes, output_iterator, input_iterator, forward_iterator, bidirectional_iterator, and random_access_iterator. The functions iterator_category, value_type, and distance_type are defined for those base classes. The effect, then, is that if you are defining a new type of iterator you can simply derive it from one of those base classes, and the iterator tag functions will automatically be defined correctly. These base classes contain no member functions or member variables, so deriving from one of them ought not to incur any overhead.

(Again, note that base classes are provided solely for the convenience of people who define iterators. If you define a class Iter that is a new kind of Bidirectional Iterator, you do not have to derive it from the base class bidirectional_iterator. You do, however, have to make sure that iterator_category, value_type, and distance_type are defined correctly for arguments of type Iter, and deriving Iter from bidirectional_iterator is usually the most convenient way to do that.)

Examples

This example uses the value_type iterator tag function in order to declare a temporary variable of an iterator's value type. Note the use of an auxiliary function, __iter_swap. This is a very common idiom: most uses of iterator tags involve auxiliary functions.
    template <class ForwardIterator1, class ForwardIterator2, class ValueType>
    inline void __iter_swap(ForwardIterator1 a, ForwardIterator2 b, ValueType*) {
    ValueType tmp = *a;
    *a = *b;
    *b = tmp;
    }

    template <class ForwardIterator1, class ForwardIterator2>
    inline void iter_swap(ForwardIterator1 a, ForwardIterator2 b) {
    __iter_swap(a, b, value_type(a));
    }

This example does exactly the same thing, using iterator_traits instead. Note how much simpler it is: the auxiliary function is no longer required.

    template <class ForwardIterator1, class ForwardIterator2>
    inline void iter_swap(ForwardIterator1 a, ForwardIterator2 b) {
        iterator_traits<ForwardIterator1>::value_type tmp = *a;
        *a = *b;
        *b = tmp;
    }

This example uses the iterator_category iterator tag function: reverse can be implemented for either Bidirectional Iterators or for Random Access Iterators, but the algorithm for Random Access Iterators is more efficient. Consequently, reverse is written to dispatch on the iterator category. This dispatch takes place at compile time, and should not incur any run-time penalty.

    template <class BidirectionalIterator>
    void __reverse(BidirectionalIterator first, BidirectionalIterator last,
           bidirectional_iterator_tag) {
    while (true)
        if (first == last || first == --last)
        return;
        else
        iter_swap(first++, last);
    }

    template <class RandomAccessIterator>
    void __reverse(RandomAccessIterator first, RandomAccessIterator last,
           random_access_iterator_tag) {
    while (first < last) iter_swap(first++, --last);
    }

    template <class BidirectionalIterator>
    inline void reverse(BidirectionalIterator first, BidirectionalIterator last) {
    __reverse(first, last, iterator_category(first));
    }

In this case, iterator_traits would not be different in any substantive way: it would still be necessary to use auxiliary functions to dispatch on the iterator category. The only difference is changing the top-level function to

    template <class BidirectionalIterator>
    inline void reverse(BidirectionalIterator first, BidirectionalIterator last) {
    __reverse(first, last,
                  iterator_traits<first>::iterator_category());
    }

Concepts

Types

  • output_iterator
  • input_iterator
  • forward_iterator
  • bidirectional_iterator
  • random_access_iterator
  • output_iterator_tag
  • input_iterator_tag
  • forward_iterator_tag
  • bidirectional_iterator_tag
  • random_access_iterator_tag
  • iterator_traits

Functions

  • iterator_category
  • value_type
  • distance_type

Notes

[1] Output Iterators have neither a distance type nor a value type; in many ways, in fact, Output Iterators aren't really iterators. Output iterators do not have a value type, because it is impossible to obtain a value from an output iterator but only to write a value through it. They do not have a distance type, similarly, because it is impossible to find the distance from one output iterator to another. Finding a distance requires a comparison for equality, and output iterators do not support operator==.

[2] The iterator_traits class relies on a C++ feature known as partial specialization. Many of today's compilers don't implement the complete standard; in particular, many compilers do not support partial specialization. If your compiler does not support partial specialization, then you will not be able to use iterator_traits, and you will have to continue to use the older iterator tag functions.

[3] Note that Trivial Iterator does not appear in this list. The Trivial Iterator concept is introduced solely for conceptual clarity; the STL does not actually define any Trivial Iterator types, so there is no need for a Trivial Iterator tag. There is, in fact, a strong reason not to define one: the C++ type system does not provide any way to distinguish between a pointer that is being used as a trivial iterator (that is, a pointer to an object that isn't part of an array) and a pointer that is being used as a Random Access Iterator into an array.

See also

Input Iterator, Output Iterator, Forward Iterator, Bidirectional Iterator, Random Access Iterator, iterator_traits, Iterator Overview


iterator_traits<Iterator>

Category: iterators | Component type: type

Description

As described in the Iterator Overview, one of the most important facts about iterators is that they have associated types. An iterator type, for example, has an associated value type: the type of object that the iterator points to. It also has an associated distance type, or difference type, a signed integral type that can be used to represent the distance between two iterators.

(Pointers, for example, are iterators; the value type of int* is int. Its distance type is ptrdiff_t, because, if p1 and p2 are pointers, the expression p1 - p2 has type ptrdiff_t.)

Generic algorithms often need to have access to these associated types; an algorithm that takes a range of iterators, for example, might need to declare a temporary variable whose type is the iterators' value type. The class iterator_traits is a mechanism that allows such declarations.

The most obvious way to allow declarations of that sort would be to require that all iterators declare nested types; an iterator I's value type, for example, would be I::value_type. That can't possibly work, though. Pointers are iterators, and pointers aren't classes; if I is (say) int*, then it's impossible to define I::value_type to be int. Instead, I's value type is written iterator_traits<I>::value_type. iterator_traits is a template class that contains nothing but nested typedefs; in addition to value_type, iterator_traits defines the nested types iterator_category, difference_type, pointer, and reference.

The library contains two definitions of iterator_traits: a fully generic one, and a specialization that is used whenever the template argument is a pointer type [1]. The fully generic version defines iterator_traits<I>::value_type as a synonym for I::value_type, iterator_traits<I>::difference_type as a synonym for I::difference_type, and so on. Since pointers don't have nested types, iterator_traits<T*> has a different definition.

The implementation of iterator_traits is actually simpler than this discussion.

  template <class Iterator>
  struct iterator_traits {
    typedef typename Iterator::iterator_category iterator_category;
    typedef typename Iterator::value_type        value_type;
    typedef typename Iterator::difference_type   difference_type;
    typedef typename Iterator::pointer           pointer;
    typedef typename Iterator::reference         reference;
  };

  template <class T>
  struct iterator_traits<T*> {
    typedef random_access_iterator_tag iterator_category;
    typedef T                          value_type;
    typedef ptrdiff_t                  difference_type;
    typedef T*                         pointer;
    typedef T&                         reference;
  };

If you are defining a new iterator type I, then you must ensure that iterator_traits<I> is defined properly. There are two ways to do this. First, you can define your iterator so that it has nested types I::value_type, I::difference_type, and so on. Second, you can explicitly specialize iterator_traits for your type. The first way is almost always more convenient, however, especially since you can easily ensure that your iterator has the appropriate nested types just by inheriting from one of the base classes input_iterator, output_iterator, forward_iterator, bidirectional_iterator, or random_access_iterator.

Note that iterator_traits is new; it was added to the draft C++ standard relatively recently. Both the old iterator tags mechanism and the new iterator_traits mechanism are currently supported [1], but the old iterator tag functions are no longer part of the standard C++ library and they will eventually be removed.

Example

This generic function returns the last element in a non-empty range. Note that there is no way to define a function with this interface in terms of the old value_type function, because the function's return type must be declared to be the iterator's value type.
template <class InputIterator>
iterator_traits<InputIterator>::value_type
last_value(InputIterator first, InputIterator last) {
  iterator_traits<InputIterator>::value_type result = *first;
  for (++first; first != last; ++first)
    result = *first;
  return result;
}

(Note: this is an example of how to use iterator_traits; it is not an example of good code. There are better ways of finding the last element in a range of bidirectional iterators, or even forward iterators.)

Definition

Defined in the standard header iterator, and in the nonstandard backward-compatibility header iterator.h.

Template parameters

Parameter | Description | Default
Iterator | The iterator type whose associated types are being accessed. |

Model of

Default Constructible, Assignable

Type requirements

  • Iterator is a model of one of the iterator concepts. (Input Iterator, Output Iterator, Forward Iterator, Bidirectional Iterator, or Random Access Iterator.)

Public base classes

None.

Members

None, except for nested types.
Member | Description
iterator_category | One of the types input_iterator_tag, output_iterator_tag, forward_iterator_tag, bidirectional_iterator_tag, or random_access_iterator_tag. An iterator's category is the most specific iterator concept that it is a model of.
value_type | Iterator's value type, as defined in the Trivial Iterator requirements.
difference_type | Iterator's distance type, as defined in the Input Iterator requirements.
pointer | Iterator's pointer type: a pointer to its value type.
reference | Iterator's reference type: a reference to its value type.

Notes

[3] The iterator_traits class relies on a C++ feature known as partial specialization. Many of today's compilers don't implement the complete standard; in particular, many compilers do not support partial specialization. If your compiler does not support partial specialization, then you will not be able to use iterator_traits, and you will have to continue using the old iterator tag functions iterator_category, distance_type, and value_type. This is one reason that those functions have not yet been removed.

See also

The iterator overview, iterator tags, input_iterator_tag, output_iterator_tag, forward_iterator_tag, bidirectional_iterator_tag, random_access_iterator_tag, input_iterator, output_iterator, forward_iterator, bidirectional_iterator, random_access_iterator


iter_swap

Category: algorithms | Component type: function

Prototype

template <class ForwardIterator1, class ForwardIterator2>
inline void iter_swap(ForwardIterator1 a, ForwardIterator2 b);

Description

Equivalent to swap(*a, *b). [1]

Definition

Declared in algo.h. The implementation is in algobase.h.

Requirements on types

  • ForwardIterator1 and ForwardIterator2 are models of Forward Iterator.
  • ForwardIterator1 and ForwardIterator2 are mutable.
  • ForwardIterator1 and ForwardIterator2 have the same value type.

Preconditions

  • ForwardIterator1 and ForwardIterator2 are dereferenceable.

Complexity

See swap for a discussion.

Example

int x = 1;
int y = 2;
assert(x == 1 && y == 2);
iter_swap(&x, &y);
assert(x == 2 && y == 1);

Notes

[1] Strictly speaking, iter_swap is redundant. It exists only for technical reasons: in some circumstances, some compilers have difficulty performing the type deduction required to interpret swap(*a, *b).

See also

swap, swap_ranges


less<T>

Category: functors | Component type: type

Description

Less<T> is a function object. Specifically, it is an Adaptable Binary Predicate, which means it is a function object that tests the truth or falsehood of some condition. If f is an object of class less<T> and x and y are objects of class T, then f(x,y) returns true if x < y and false otherwise.

Example

Finds the first negative element in a list.
list<int> L;
...
list<int>::iterator first_negative =
       find_if(L.begin(), L.end(), bind2nd(less<int>(), 0));
assert(first_negative == L.end() || *first_negative < 0);

Definition

Defined in the standard header functional, and in the nonstandard backward-compatibility header function.h.

Template parameters

Parameter | Description | Default
T | The type of less's arguments. |

Model of

Adaptable Binary Predicate, DefaultConstructible

Type requirements

T is LessThan Comparable.

Public base classes

binary_function<T, T, bool>.

Members

Member | Where defined | Description
first_argument_type | Adaptable Binary Predicate | The type of the first argument: T
second_argument_type | Adaptable Binary Predicate | The type of the second argument: T
result_type | Adaptable Binary Predicate | The type of the result: bool
less() | DefaultConstructible | The default constructor.
bool operator()(const T& x, const T& y) | Binary Function | Function call operator. The return value is x < y.

New members

All of less's members are defined in the Adaptable Binary Predicate and DefaultConstructible requirements. less does not introduce any new members.

Notes

See also

The function object overview, Strict Weak Ordering, Adaptable Binary Predicate, LessThan Comparable, equal_to, not_equal_to, greater, greater_equal, less_equal


LessThan Comparable

Category: utilities | Component type: concept

Description

A type is LessThanComparable if it is ordered: it must be possible to compare two objects of that type using operator<, and operator< must be a partial ordering.

Refinement of

Associated types

Notation

X | A type that is a model of LessThanComparable
x, y, z | Object of type X

Definitions

Consider the relation !(x < y) && !(y < x). If this relation is transitive (that is, if !(x < y) && !(y < x) && !(y < z) && !(z < y) implies !(x < z) && !(z < x)), then it satisfies the mathematical definition of an equivalence relation. In this case, operator< is a strict weak ordering.

If operator< is a strict weak ordering, and if each equivalence class has only a single element, then operator< is a total ordering.

Valid expressions

Name | Expression | Type requirements | Return type
Less | x < y |  | Convertible to bool
Greater | x > y |  | Convertible to bool
Less or equal | x <= y |  | Convertible to bool
Greater or equal | x >= y |  | Convertible to bool

Expression semantics

Name | Expression | Precondition | Semantics | Postcondition
Less | x < y | x and y are in the domain of < |  |
Greater | x > y | x and y are in the domain of < | Equivalent to y < x [1] |
Less or equal | x <= y | x and y are in the domain of < | Equivalent to !(y < x) [1] |
Greater or equal | x >= y | x and y are in the domain of < | Equivalent to !(x < y) [1] |

Complexity guarantees

Invariants

Irreflexivity | x < x must be false.
Antisymmetry | x < y implies !(y < x) [2]
Transitivity | x < y and y < z implies x < z [3]

Models

  • int

Notes

[1] Only operator< is fundamental; the other inequality operators are essentially syntactic sugar.

[2] Antisymmetry is a theorem, not an axiom: it follows from irreflexivity and transitivity.

[3] Because of irreflexivity and transitivity, operator< always satisfies the definition of a partial ordering. The definition of a strict weak ordering is stricter, and the definition of a total ordering is stricter still.

See also

EqualityComparable, StrictWeakOrdering


less_equal<T>

Category: functors | Component type: type

Description

Less_equal<T> is a function object. Specifically, it is an Adaptable Binary Predicate, which means it is a function object that tests the truth or falsehood of some condition. If f is an object of class less_equal<T> and x and y are objects of class T, then f(x,y) returns true if x <= y and false otherwise.

Example

Finds the first non-positive element in a list.
list<int> L;
...
list<int>::iterator first_nonpositive =
       find_if(L.begin(), L.end(), bind2nd(less_equal<int>(), 0));
assert(first_nonpositive == L.end() || *first_nonpositive <= 0);

Definition

Defined in the standard header functional, and in the nonstandard backward-compatibility header function.h.

Template parameters

Parameter | Description | Default
T | The type of less_equal's arguments. |

Model of

Adaptable Binary Predicate, DefaultConstructible

Type requirements

T is LessThan Comparable.

Public base classes

binary_function<T, T, bool>.

Members

Member | Where defined | Description
first_argument_type | Adaptable Binary Predicate | The type of the first argument: T
second_argument_type | Adaptable Binary Predicate | The type of the second argument: T
result_type | Adaptable Binary Predicate | The type of the result: bool
less_equal() | DefaultConstructible | The default constructor.
bool operator()(const T& x, const T& y) | Binary Function | Function call operator. The return value is x <= y.

New members

All of less_equal's members are defined in the Adaptable Binary Predicate and DefaultConstructible requirements. Less_equal does not introduce any new members.

Notes

See also

The function object overview, Adaptable Binary Predicate, equal_to, not_equal_to, greater, less, greater_equal,


lexicographical_compare

Category: algorithms | Component type: function

Prototype

Lexicographical_compare is an overloaded name; there are actually two lexicographical_compare functions.
template <class InputIterator1, class InputIterator2>
bool lexicographical_compare(InputIterator1 first1, InputIterator1 last1,
                             InputIterator2 first2, InputIterator2 last2);

template <class InputIterator1, class InputIterator2, class BinaryPredicate>
bool lexicographical_compare(InputIterator1 first1, InputIterator1 last1,
                             InputIterator2 first2, InputIterator2 last2,
                             BinaryPredicate comp);

Description

Lexicographical_compare returns true if the range of elements [first1, last1) is lexicographically less than the range of elements [first2, last2), and false otherwise. Lexicographical comparison means "dictionary" (element-by-element) ordering. That is, [first1, last1) is less than [first2, last2) if *first1 is less than *first2, and greater if *first1 is greater than *first2. If the two first elements are equivalent then lexicographical_compare compares the two second elements, and so on. As with ordinary dictionary order, the first range is considered to be less than the second if every element in the first range is equal to the corresponding element in the second but the second contains more elements.

The two versions of lexicographical_compare differ in how they define whether one element is less than another. The first version compares objects using operator<, and the second compares objects using a function object comp.

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

For the first version:
  • InputIterator1 is a model of Input Iterator.
  • InputIterator2 is a model of Input Iterator.
  • InputIterator1's value type is a model of LessThan Comparable.
  • InputIterator2's value type is a model of LessThan Comparable.
  • If v1 is an object of InputIterator1's value type and v2 is an object of InputIterator2's value type, then both v1 < v2 and v2 < v1 are defined.
For the second version:
  • InputIterator1 is a model of Input Iterator.
  • InputIterator2 is a model of Input Iterator.
  • BinaryPredicate is a model of Binary Predicate.
  • InputIterator1's value type is convertible to BinaryPredicate's first argument type and second argument type.
  • InputIterator2's value type is convertible to BinaryPredicate's first argument type and second argument type.

Preconditions

  • [first1, last1) is a valid range.
  • [first2, last2) is a valid range.

Complexity

Linear. At most 2 * min(last1 - first1, last2 - first2) comparisons.

Example

int main()
{
  int A1[] = {3, 1, 4, 1, 5, 9, 3};
  int A2[] = {3, 1, 4, 2, 8, 5, 7};
  int A3[] = {1, 2, 3, 4};
  int A4[] = {1, 2, 3, 4, 5};

  const int N1 = sizeof(A1) / sizeof(int);
  const int N2 = sizeof(A2) / sizeof(int);
  const int N3 = sizeof(A3) / sizeof(int);
  const int N4 = sizeof(A4) / sizeof(int);

  bool C12 = lexicographical_compare(A1, A1 + N1, A2, A2 + N2);
  bool C34 = lexicographical_compare(A3, A3 + N3, A4, A4 + N4);

  cout << "A1[] < A2[]: " << (C12 ? "true" : "false") << endl;
  cout << "A3[] < A4[]: " << (C34 ? "true" : "false") << endl;
}

Notes

See also

equal, mismatch, lexicographical_compare_3way, search, LessThan Comparable, Strict Weak Ordering, sort


lexicographical_compare_3way

Category: algorithms | Component type: function

Prototype

template <class InputIterator1, class InputIterator2>
int lexicographical_compare_3way(InputIterator1 first1, InputIterator1 last1,
                                 InputIterator2 first2, InputIterator2 last2);

Description

Lexicographical_compare_3way is essentially a generalization of the function strcmp from the standard C library: it returns a negative number if the range [first1, last1) is lexicographically less than the range [first2, last2), a positive number if [first2, last2) is lexicographically less than [first1, last1), and zero if neither range is lexicographically less than the other. [1]

As with lexicographical_compare, lexicographical comparison means "dictionary" (element-by-element) ordering. That is, lexicographical_compare_3way returns a negative number if *first1 is less than *first2, and a positive number if *first1 is greater than *first2. If the two first elements are equivalent [2] then lexicographical_compare_3way compares the two second elements, and so on. Lexicographical_compare_3way returns 0 only if the two ranges [first1, last1) and [first2, last2) have the same length and if every element in the first range is equivalent to its corresponding element in the second.

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h. This function is an SGI extension; it is not part of the C++ standard.

Requirements on types

  • InputIterator1 is a model of Input Iterator.
  • InputIterator2 is a model of Input Iterator.
  • InputIterator1's value type is a model of LessThan Comparable.
  • InputIterator2's value type is a model of LessThan Comparable.
  • If v1 is an object of InputIterator1's value type and v2 is an object of InputIterator2's value type, then both v1 < v2 and v2 < v1 are defined.
  • Operator< is a strict weak ordering, as defined in the LessThan Comparable requirements.

Preconditions

  • [first1, last1) is a valid range.
  • [first2, last2) is a valid range.

Complexity

Linear. At most 2 * min(last1 - first1, last2 - first2) comparisons.

Example

int main()
{
  int A1[] = {3, 1, 4, 2, 8, 5, 7};
  int A2[] = {3, 1, 4, 1, 5, 9, 3};
  int A3[] = {1, 2, 3, 4};
  int A4[] = {1, 2, 3, 4, 5};

  const int N1 = sizeof(A1) / sizeof(int);
  const int N2 = sizeof(A2) / sizeof(int);
  const int N3 = sizeof(A3) / sizeof(int);
  const int N4 = sizeof(A4) / sizeof(int);

  int C12 = lexicographical_compare_3way(A1, A1 + N1, A2, A2 + N2);
  int C34 = lexicographical_compare_3way(A3, A3 + N3, A4, A4 + N4);

  cout << "A1[] and A2[]: " << C12 << endl;
  cout << "A3[] and A4[]: " << C34 << endl;
}

Notes

[1] Lexicographical_compare_3way is almost, but not quite, redundant: the call lexicographical_compare_3way(f1,l1, f2,l2) could be written as lexicographical_compare(f1,l1, f2,l2) ? -1 : (lexicographical_compare(f2,l2, f1,l1) ? 1 : 0). The single call to lexicographical_compare_3way, however, is much faster than the two calls to lexicographical_compare.

[2] "Equivalent", not "equal", because two equivalent elements (that is, two elements with the property that neither one is less than the other) are not necessarily equal. Operator< is required to induce a strict weak ordering, not necessarily a total ordering. See the LessThan Comparable requirements for a discussion.

See also

lexicographical_compare, equal, mismatch, search, LessThan Comparable, Strict Weak Ordering, sort


list<T, Alloc>

Category: containers | Component type: type

Description

A list is a doubly linked list. That is, it is a Sequence that supports both forward and backward traversal, and (amortized) constant time insertion and removal of elements at the beginning or the end, or in the middle. Lists have the important property that insertion and splicing do not invalidate iterators to list elements, and that even removal invalidates only the iterators that point to the elements that are removed. The ordering of iterators may be changed (that is, list<T>::iterator might have a different predecessor or successor after a list operation than it did before), but the iterators themselves will not be invalidated or made to point to different elements unless that invalidation or mutation is explicit. [1]

Note that singly linked lists, which only support forward traversal, are also sometimes useful. If you do not need backward traversal, then slist may be more efficient than list.

Definition

Defined in the standard header list, and in the nonstandard backward-compatibility header list.h.

Example

list<int> L;
L.push_back(0);
L.push_front(1);
L.insert(++L.begin(), 2);
copy(L.begin(), L.end(), ostream_iterator<int>(cout, " "));
// The values that are printed are 1 2 0

Template parameters

Parameter | Description | Default
T | The list's value type: the type of object that is stored in the list. |
Alloc | The list's allocator, used for all internal memory management. | alloc

Model of

Reversible Container, Front Insertion Sequence, Back Insertion Sequence.

Type requirements

None, except for those imposed by the requirements of Reversible Container, Front Insertion Sequence, and Back Insertion Sequence.

Public base classes

None.

Members

Member | Where defined | Description
value_type | Container | The type of object, T, stored in the list.
pointer | Container | Pointer to T.
reference | Container | Reference to T
const_reference | Container | Const reference to T
size_type | Container | An unsigned integral type.
difference_type | Container | A signed integral type.
iterator | Container | Iterator used to iterate through a list.
const_iterator | Container | Const iterator used to iterate through a list.
reverse_iterator | Reversible Container | Iterator used to iterate backwards through a list.
const_reverse_iterator | Reversible Container | Const iterator used to iterate backwards through a list.
iterator begin() | Container | Returns an iterator pointing to the beginning of the list.
iterator end() | Container | Returns an iterator pointing to the end of the list.
const_iterator begin() const | Container | Returns a const_iterator pointing to the beginning of the list.
const_iterator end() const | Container | Returns a const_iterator pointing to the end of the list.
reverse_iterator rbegin() | Reversible Container | Returns a reverse_iterator pointing to the beginning of the reversed list.
reverse_iterator rend() | Reversible Container | Returns a reverse_iterator pointing to the end of the reversed list.
const_reverse_iterator rbegin() const | Reversible Container | Returns a const_reverse_iterator pointing to the beginning of the reversed list.
const_reverse_iterator rend() const | Reversible Container | Returns a const_reverse_iterator pointing to the end of the reversed list.
size_type size() const | Container | Returns the size of the list. Note: you should not assume that this function is constant time. It is permitted to be O(N), where N is the number of elements in the list. If you wish to test whether a list is empty, you should write L.empty() rather than L.size() == 0.
size_type max_size() const | Container | Returns the largest possible size of the list.
bool empty() const | Container | true if the list's size is 0.
list() | Container | Creates an empty list.
list(size_type n) | Sequence | Creates a list with n elements, each of which is a copy of T().
list(size_type n, const T& t) | Sequence | Creates a list with n copies of t.
list(const list&) | Container | The copy constructor.
template <class InputIterator>
list(InputIterator f, InputIterator l)
[2]
Sequence Creates a list with a copy of a range.
~list() | Container | The destructor.
list& operator=(const list&) | Container | The assignment operator
reference front() | Front Insertion Sequence | Returns the first element.
const_reference front() const | Front Insertion Sequence | Returns the first element.
reference back() | Sequence | Returns the last element.
const_reference back() const | Back Insertion Sequence | Returns the last element.
void push_front(const T&) | Front Insertion Sequence | Inserts a new element at the beginning.
void push_back(const T&) | Back Insertion Sequence | Inserts a new element at the end.
void pop_front() | Front Insertion Sequence | Removes the first element.
void pop_back() | Back Insertion Sequence | Removes the last element.
void swap(list&) | Container | Swaps the contents of two lists.
iterator insert(iterator pos, const T& x) | Sequence | Inserts x before pos.
template <class InputIterator>
void insert(iterator pos,
            InputIterator f,
            InputIterator l)
[2]
Sequence Inserts the range [f, l) before pos.
void insert(iterator pos,
            size_type n, const T& x)
Sequence Inserts n copies of x before pos.
iterator erase(iterator pos) | Sequence | Erases the element at position pos.
iterator erase(iterator first, iterator last) | Sequence | Erases the range [first, last)
void clear() | Sequence | Erases all of the elements.
void resize(n, t = T()) | Sequence | Inserts or erases elements at the end such that the size becomes n.
void splice(iterator pos, list& L) | list | See below.
void splice(iterator pos,
            list& L,
            iterator i)
list See below.
void splice(iterator pos,
            list& L,
            iterator f, iterator l)
list See below.
void remove(const T& value) | list | See below.
void unique() | list | See below.
void merge(list& L) | list | See below.
void sort() | list | See below.
bool operator==(const list&,
                const list&)
Forward Container Tests two lists for equality. This is a global function, not a member function.
bool operator<(const list&,
               const list&)
Forward Container Lexicographical comparison. This is a global function, not a member function.

New members

These members are not defined in the Reversible Container, Front Insertion Sequence, and Back Insertion Sequence requirements, but are specific to list.
Function | Description
void splice(iterator position,
            list<T, Alloc>& x);
position must be a valid iterator in *this, and x must be a list that is distinct from *this. (That is, it is required that &x != this.) All of the elements of x are inserted before position and removed from x. All iterators remain valid, including iterators that point to elements of x. [3] This function is constant time.

void splice(iterator position,
            list<T, Alloc>& x,
            iterator i);
position must be a valid iterator in *this, and i must be a dereferenceable iterator in x. Splice moves the element pointed to by i from x to *this, inserting it before position. All iterators remain valid, including iterators that point to elements of x. [3] If position == i or position == ++i, this function is a null operation. This function is constant time.

void splice(iterator position,
            list<T, Alloc>& x,
            iterator f, iterator l);
position must be a valid iterator in *this, and [first, last) must be a valid range in x. position may not be an iterator in the range [first, last). Splice moves the elements in [first, last) from x to *this, inserting them before position. All iterators remain valid, including iterators that point to elements of x. [3] This function is constant time.
void remove(const T& val); | Removes all elements that compare equal to val. The relative order of elements that are not removed is unchanged, and iterators to elements that are not removed remain valid. This function is linear time: it performs exactly size() comparisons for equality.
template<class Predicate>
void remove_if(Predicate p);
[4]
Removes all elements *i such that p(*i) is true. The relative order of elements that are not removed is unchanged, and iterators to elements that are not removed remain valid. This function is linear time: it performs exactly size() applications of p.
void unique(); | Removes all but the first element in every consecutive group of equal elements. The relative order of elements that are not removed is unchanged, and iterators to elements that are not removed remain valid. This function is linear time: it performs exactly size() - 1 comparisons for equality.
template<class BinaryPredicate>
void unique(BinaryPredicate p);
[4]
Removes all but the first element in every consecutive group of equivalent elements, where two elements *i and *j are considered equivalent if p(*i, *j) is true. The relative order of elements that are not removed is unchanged, and iterators to elements that are not removed remain valid. This function is linear time: it performs exactly size() - 1 comparisons for equality.
void merge(list<T, Alloc>& x); | Both *this and x must be sorted according to operator<, and they must be distinct. (That is, it is required that &x != this.) This function removes all of x's elements and inserts them in order into *this. The merge is stable; that is, if an element from *this is equivalent to one from x, then the element from *this will precede the one from x. All iterators to elements in *this and x remain valid. This function is linear time: it performs at most size() + x.size() - 1 comparisons.
template<class BinaryPredicate>
void merge(list<T, Alloc>& x,
           BinaryPredicate Comp);
[4]
Comp must be a comparison function that induces a strict weak ordering (as defined in the LessThan Comparable requirements) on objects of type T, and both *this and x must be sorted according to that ordering. The lists x and *this must be distinct. (That is, it is required that &x != this.) This function removes all of x's elements and inserts them in order into *this. The merge is stable; that is, if an element from *this is equivalent to one from x, then the element from *this will precede the one from x. All iterators to elements in *this and x remain valid. This function is linear time: it performs at most size() + x.size() - 1 applications of Comp.
void reverse(); | Reverses the order of elements in the list. All iterators remain valid and continue to point to the same elements. [5] This function is linear time.
void sort(); | Sorts *this according to operator<. The sort is stable, that is, the relative order of equivalent elements is preserved. All iterators remain valid and continue to point to the same elements. [6] The number of comparisons is approximately N log N, where N is the list's size.
template<class BinaryPredicate>
void sort(BinaryPredicate comp);
[4]
Comp must be a comparison function that induces a strict weak ordering (as defined in the LessThan Comparable requirements on objects of type T. This function sorts the list *this according to Comp. The sort is stable, that is, the relative order of equivalent elements is preserved. All iterators remain valid and continue to point to the same elements. [6] The number of comparisons is approximately N log N, where N is the list's size.

Notes

[1] A comparison with vector is instructive. Suppose that i is a valid vector<T>::iterator. If an element is inserted or removed in a position that precedes i, then this operation will either result in i pointing to a different element than it did before, or else it will invalidate i entirely. (A vector<T>::iterator will be invalidated, for example, if an insertion requires a reallocation.) However, suppose that i and j are both iterators into a vector, and there exists some integer n such that i == j + n. In that case, even if elements are inserted into the vector and i and j point to different elements, the relation between the two iterators will still hold. A list is exactly the opposite: iterators will not be invalidated, and will not be made to point to different elements, but, for list iterators, the predecessor/successor relationship is not invariant.

[2] This member function relies on member template functions, which at present (early 1998) are not supported by all compilers. If your compiler supports member templates, you can call this function with any type of input iterator. If your compiler does not yet support member templates, though, then the arguments must either be of type const value_type* or of type list::const_iterator.

[3] A similar property holds for all versions of insert() and erase(). List<T, Alloc>::insert() never invalidates any iterators, and list<T, Alloc>::erase() only invalidates iterators pointing to the elements that are actually being erased.

[4] This member function relies on member template functions, which at present (early 1998) are not supported by all compilers. You can only use this member function if your compiler supports member templates.

[5] If L is a list, note that L.reverse() and reverse(L.begin(), L.end()) are both correct ways of reversing the list. They differ in that L.reverse() will preserve the value that each iterator into L points to but will not preserve the iterators' predecessor/successor relationships, while reverse(L.begin(), L.end()) will not preserve the value that each iterator points to but will preserve the iterators' predecessor/successor relationships. Note also that the algorithm reverse(L.begin(), L.end()) will use T's assignment operator, while the member function L.reverse() will not.

[6] The sort algorithm works only for random access iterators. In principle, however, it would be possible to write a sort algorithm that also accepted bidirectional iterators. Even if there were such a version of sort, it would still be useful for list to have a sort member function. That is, sort is provided as a member function not only for the sake of efficiency, but also because of the property that it preserves the values that list iterators point to.

See also

Bidirectional Iterator, Reversible Container, Sequence, slist vector.


logical_and<T>

Category: functors | Component type: type

Description

Logical_and<T> is a function object; specifically, it is an Adaptable Binary Predicate, which means it is a function object that tests the truth or falsehood of some condition. If f is an object of class logical_and<T> and x and y are objects of class T (where T is convertible to bool) then f(x,y) returns true if and only if both x and y are true. [1]

Example

Finds the first element in a list that lies in the range from 1 to 10.
list<int> L;
...
list<int>::iterator in_range =
     find_if(L.begin(), L.end(),
             compose2(logical_and<bool>(),
                      bind2nd(greater_equal<int>(), 1),
                      bind2nd(less_equal<int>(), 10)));
assert(in_range == L.end() || (*in_range >= 1 && *in_range <= 10));

Definition

Defined in the standard header functional, and in the nonstandard backward-compatibility header function.h.

Template parameters

Parameter | Description | Default
T | The type of logical_and's arguments |

Model of

Adaptable Binary Predicate, DefaultConstructible

Type requirements

T must be convertible to bool.

Public base classes

binary_function<T, T, bool>

Members

Member | Where defined | Description
first_argument_type | Adaptable Binary Function | The type of the first argument: T
second_argument_type | Adaptable Binary Function | The type of the second argument: T
result_type | Adaptable Binary Function | The type of the result: bool
bool operator()(const T& x, const T& y) const | Binary Function | Function call operator. The return value is x && y.
logical_and() | Default Constructible | The default constructor.

New members

All of logical_and's members are defined in the Adaptable Binary Function and Default Constructible requirements. Logical_and does not introduce any new members.

Notes

[1] Logical_and and logical_or are not very useful by themselves. They are mainly useful because, when combined with the function object adaptor binary_compose, they perform logical operations on other function objects.

See also

The function object overview, logical_or, logical_not.


logical_not<T>

Category: functors | Component type: type

Description

Logical_not<T> is a function object; specifically, it is an Adaptable Predicate, which means it is a function object that tests the truth or falsehood of some condition. If f is an object of class logical_not<T> and x is an object of class T (where T is convertible to bool) then f(x) returns true if and only if x is false.

Example

Transforms a vector of bool into its logical complement.
vector<bool> V;
...
transform(V.begin(), V.end(), V.begin(), logical_not<bool>());

Definition

Defined in the standard header functional, and in the nonstandard backward-compatibility header function.h.

Template parameters

Parameter | Description | Default
T | The type of logical_not's argument |

Model of

Adaptable Predicate, DefaultConstructible

Type requirements

T must be convertible to bool.

Public base classes

unary_function<T, bool>

Members

Member | Where defined | Description
argument_type | Adaptable Unary Function | The type of the second argument: T
result_type | Adaptable Unary Function | The type of the result: bool
bool operator()(const T& x) const | Unary Function | Function call operator. The return value is !x.
logical_not() | Default Constructible | The default constructor.

Notes

See also

The function object overview, logical_or, logical_and.


logical_or<T>

Category: functors | Component type: type

Description

Logical_or<T> is a function object; specifically, it is an Adaptable Binary Predicate, which means it is a function object that tests the truth or falsehood of some condition. If f is an object of class logical_and<T> and x and y are objects of class T (where T is convertible to bool) then f(x,y) returns true if and only if either x or y is true. [1]

Example

Finds the first instance of either ' ' or '\n' in a string.
char str[MAXLEN];
...
const char* wptr = find_if(str, str + MAXLEN,
                           compose2(logical_or<bool>(),
                                    bind2nd(equal_to<char>(), ' '),
                                    bind2nd(equal_to<char>(), '\n')));
assert(wptr == str + MAXLEN || *wptr == ' ' || *wptr == '\n');

Definition

Defined in the standard header functional, and in the nonstandard backward-compatibility header function.h.

Template parameters

Parameter | Description | Default
T | The type of logical_or's arguments |

Model of

Adaptable Binary Predicate, DefaultConstructible

Type requirements

T must be convertible to bool.

Public base classes

binary_function<T, T, bool>

Members

Member | Where defined | Description
first_argument_type | Adaptable Binary Function | The type of the first argument: T
second_argument_type | Adaptable Binary Function | The type of the second argument: T
result_type | Adaptable Binary Function | The type of the result: bool
bool operator()(const T& x, const T& y) const | Binary Function | Function call operator. The return value is x || y.
logical_or() | Default Constructible | The default constructor.

New members

All of logical_or's members are defined in the Adaptable Binary Function and Default Constructible requirements. Logical_or does not introduce any new members.

Notes

[1] Logical_and and logical_or are not very useful by themselves. They are mainly useful because, when combined with the function object adaptor binary_compose, they perform logical operations on other function objects.

See also

The function object overview, logical_and, logical_not.


lower_bound

Category: algorithms | Component type: function

Prototype

Lower_bound is an overloaded name; there are actually two lower_bound functions.
template <class ForwardIterator, class LessThanComparable>
ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last,
                            const LessThanComparable& value);

template <class ForwardIterator, class T, class StrictWeakOrdering>
ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last,
                            const T& value, StrictWeakOrdering comp);

Description

Lower_bound is a version of binary search: it attempts to find the element value in an ordered range [first, last) [1]. Specifically, it returns the first position where value could be inserted without violating the ordering. [2] The first version of lower_bound uses operator< for comparison, and the second uses the function object comp.

The first version of lower_bound returns the furthermost iterator i in [first, last) such that, for every iterator j in [first, i), *j < value.

The second version of lower_bound returns the furthermost iterator i in [first, last) such that, for every iterator j in [first, i), comp(*j, value) is true.

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

For the first version:
  • ForwardIterator is a model of Forward Iterator.
  • LessThanComparable is a model of LessThan Comparable.
  • The ordering on objects of type LessThanComparable is a strict weak ordering, as defined in the LessThan Comparable requirements.
  • ForwardIterator's value type is the same type as LessThanComparable.
For the second version:
  • ForwardIterator is a model of Forward Iterator.
  • StrictWeakOrdering is a model of Strict Weak Ordering.
  • ForwardIterator's value type is the same type as T.
  • ForwardIterator's value type is convertible to StrictWeakOrdering's argument type.

Preconditions

For the first version:
  • [first, last) is a valid range.
  • [first, last) is ordered in ascending order according to operator<. That is, for every pair of iterators i and j in [first, last) such that i precedes j, *j < *i is false.
For the second version:
  • [first, last) is a valid range.
  • [first, last) is ordered in ascending order according to the function object comp. That is, for every pair of iterators i and j in [first, last) such that i precedes j, comp(*j, *i) is false.

Complexity

The number of comparisons is logarithmic: at most log(last - first) + 1. If ForwardIterator is a Random Access Iterator then the number of steps through the range is also logarithmic; otherwise, the number of steps is proportional to last - first. [3]

Example

int main()
{
  int A[] = { 1, 2, 3, 3, 3, 5, 8 };
  const int N = sizeof(A) / sizeof(int);

  for (int i = 1; i <= 10; ++i) {
    int* p = lower_bound(A, A + N, i);
    cout << "Searching for " << i << ".  ";
    cout << "Result: index = " << p - A << ", ";
    if (p != A + N)
      cout << "A[" << p - A << "] == " << *p << endl;
    else
      cout << "which is off-the-end." << endl;
  }
}
The output is:
Searching for 1.  Result: index = 0, A[0] == 1
Searching for 2.  Result: index = 1, A[1] == 2
Searching for 3.  Result: index = 2, A[2] == 3
Searching for 4.  Result: index = 5, A[5] == 5
Searching for 5.  Result: index = 5, A[5] == 5
Searching for 6.  Result: index = 6, A[6] == 8
Searching for 7.  Result: index = 6, A[6] == 8
Searching for 8.  Result: index = 6, A[6] == 8
Searching for 9.  Result: index = 7, which is off-the-end.
Searching for 10.  Result: index = 7, which is off-the-end.

Notes

[1] Note that you may use an ordering that is a strict weak ordering but not a total ordering; that is, there might be values x and y such that x < y, x > y, and x == y are all false. (See the LessThan Comparable requirements for a more complete discussion.) Finding value in the range [first, last), then, doesn't mean finding an element that is equal to value but rather one that is equivalent to value: one that is neither greater than nor less than value. If you're using a total ordering, however (if you're using strcmp, for example, or if you're using ordinary arithmetic comparison on integers), then you can ignore this technical distinction: for a total ordering, equality and equivalence are the same.

[2] If an element that is equivalent to [1] value is already present in the range [first, last), then the return value of lower_bound will be an iterator that points to that element.

[3] This difference between Random Access Iterators and Forward Iterators is simply because advance is constant time for Random Access Iterators and linear time for Forward Iterators.

See also

upper_bound, equal_range, binary_search


make_heap

Category: algorithms | Component type: function

Prototype

Make_heap is an overloaded name; there are actually two make_heap functions.
template <class RandomAccessIterator>
void make_heap(RandomAccessIterator first, RandomAccessIterator last);

template <class RandomAccessIterator, class StrictWeakOrdering>
void make_heap(RandomAccessIterator first, RandomAccessIterator last,
               StrictWeakOrdering comp);

Description

Make_heap turns the range [first, last) into a heap [1].

The two versions of make_heap differ in how they define whether one element is less than another. The first version compares objects using operator<, and the second compares objects using a function object comp. In the first version the postcondition is that is_heap(first, last) is true, and in the second version the postcondition is that is_heap(first, last, comp) is true.

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

For the first version:
  • RandomAccessIterator is a model of Random Access Iterator.
  • RandomAccessIterator is mutable.
  • RandomAccessIterator's value type is a model of LessThan Comparable.
  • The ordering on objects of RandomAccessIterator's value type is a strict weak ordering, as defined in the LessThan Comparable requirements.
For the second version:
  • RandomAccessIterator is a model of Random Access Iterator.
  • RandomAccessIterator is mutable.
  • StrictWeakOrdering is a model of Strict Weak Ordering.
  • RandomAccessIterator's value type is convertible to StrictWeakOrdering's argument type.

Preconditions

  • [first, last) is a valid range.

Complexity

Linear. At most 3*(last - first) comparisons.

Example

int main()
{
  int A[] = {1, 4, 2, 8, 5, 7};
  const int N = sizeof(A) / sizeof(int);

  make_heap(A, A+N);
  copy(A, A+N, ostream_iterator<int>(cout, " "));
  cout << endl;

  sort_heap(A, A+N);
  copy(A, A+N, ostream_iterator<int>(cout, " "));
  cout << endl;
}

Notes

[1] A heap is a particular way of ordering the elements in a range of Random Access Iterators [f, l). The reason heaps are useful (especially for sorting, or as priority queues) is that they satisfy two important properties. First, *f is the largest element in the heap. Second, it is possible to add an element to a heap (using push_heap), or to remove *f, in logarithmic time. Internally, a heap is simply a tree represented as a sequential range. The tree is constructed so that that each node is less than or equal to its parent node.

See also

push_heap, pop_heap, sort_heap, sort, is_heap


map<Key, Data, Compare, Alloc>

Category: containers | Component type: type

Description

Map is a Sorted Associative Container that associates objects of type Key with objects of type Data. Map is a Pair Associative Container, meaning that its value type is pair<const Key, Data>. It is also a Unique Associative Container, meaning that no two elements have the same key.

Map has the important property that inserting a new element into a map does not invalidate iterators that point to existing elements. Erasing an element from a map also does not invalidate any iterators, except, of course, for iterators that actually point to the element that is being erased.

Example

struct ltstr
{
  bool operator()(const char* s1, const char* s2) const
  {
    return strcmp(s1, s2) < 0;
  }
};

int main()
{
  map<const char*, int, ltstr> months;

  months["january"] = 31;
  months["february"] = 28;
  months["march"] = 31;
  months["april"] = 30;
  months["may"] = 31;
  months["june"] = 30;
  months["july"] = 31;
  months["august"] = 31;
  months["september"] = 30;
  months["october"] = 31;
  months["november"] = 30;
  months["december"] = 31;

  cout << "june -> " << months["june"] << endl;
  map<const char*, int, ltstr>::iterator cur  = months.find("june");
  map<const char*, int, ltstr>::iterator prev = cur;
  map<const char*, int, ltstr>::iterator next = cur;
  ++next;
  --prev;
  cout << "Previous (in alphabetical order) is " << (*prev).first << endl;
  cout << "Next (in alphabetical order) is " << (*next).first << endl;
}

Definition

Defined in the standard header map, and in the nonstandard backward-compatibility header map.h.

Template parameters

Parameter | Description | Default
Key | The map's key type. This is also defined as map::key_type. |
Data | The map's data type. This is also defined as map::data_type. |
Compare | The key comparison function, a Strict Weak Ordering whose argument type is key_type; it returns true if its first argument is less than its second argument, and false otherwise. This is also defined as map::key_compare. | less<Key>
Alloc | The map's allocator, used for all internal memory management. | alloc

Model of

Unique Sorted Associative Container, Pair Associative Container

Type requirements

  • Data is Assignable.
  • Compare is a Strict Weak Ordering whose argument type is Key.
  • Alloc is an Allocator.

Public base classes

None.

Members

Member | Where defined | Description
key_type | Associative Container | The map's key type, Key.
data_type | Pair Associative Container | The type of object associated with the keys.
value_type | Pair Associative Container | The type of object, pair<const key_type, data_type>, stored in the map.
key_compare | Sorted Associative Container | Function object that compares two keys for ordering.
value_compare | Sorted Associative Container | Function object that compares two values for ordering.
pointer | Container | Pointer to T.
reference | Container | Reference to T
const_reference | Container | Const reference to T
size_type | Container | An unsigned integral type.
difference_type | Container | A signed integral type.
iterator | Container | Iterator used to iterate through a map. [1]
const_iterator | Container | Const iterator used to iterate through a map.
reverse_iterator | Reversible Container | Iterator used to iterate backwards through a map. [1]
const_reverse_iterator | Reversible Container | Const iterator used to iterate backwards through a map.
iterator begin() | Container | Returns an iterator pointing to the beginning of the map.
iterator end() | Container | Returns an iterator pointing to the end of the map.
const_iterator begin() const | Container | Returns a const_iterator pointing to the beginning of the map.
const_iterator end() const | Container | Returns a const_iterator pointing to the end of the map.
reverse_iterator rbegin() | Reversible Container | Returns a reverse_iterator pointing to the beginning of the reversed map.
reverse_iterator rend() | Reversible Container | Returns a reverse_iterator pointing to the end of the reversed map.
const_reverse_iterator rbegin() const | Reversible Container | Returns a const_reverse_iterator pointing to the beginning of the reversed map.
const_reverse_iterator rend() const | Reversible Container | Returns a const_reverse_iterator pointing to the end of the reversed map.
size_type size() const | Container | Returns the size of the map.
size_type max_size() const | Container | Returns the largest possible size of the map.
bool empty() const | Container | true if the map's size is 0.
key_compare key_comp() const | Sorted Associative Container | Returns the key_compare object used by the map.
value_compare value_comp() const | Sorted Associative Container | Returns the value_compare object used by the map.
map() | Container | Creates an empty map.
map(const key_compare& comp) | Sorted Associative Container | Creates an empty map, using comp as the key_compare object.
template <class InputIterator>
map(InputIterator f, InputIterator l)
[2]
Unique Sorted Associative Container Creates a map with a copy of a range.
template <class InputIterator>
map(InputIterator f, InputIterator l,
    const key_compare& comp)
[2]
Unique Sorted Associative Container Creates a map with a copy of a range, using comp as the key_compare object.
map(const map&) | Container | The copy constructor.
map& operator=(const map&) | Container | The assignment operator
void swap(map&) | Container | Swaps the contents of two maps.
pair<iterator, bool>
insert(const value_type& x)
Unique Associative Container Inserts x into the map.
iterator insert(iterator pos,
                const value_type& x)
Unique Sorted Associative Container Inserts x into the map, using pos as a hint to where it will be inserted.
template <class InputIterator>
void insert(InputIterator, InputIterator)
[2]
Unique Sorted Associative Container Inserts a range into the map.
void erase(iterator pos) | Associative Container | Erases the element pointed to by pos.
size_type erase(const key_type& k) | Associative Container | Erases the element whose key is k.
void erase(iterator first, iterator last) | Associative Container | Erases all elements in a range.
void clear() | Associative Container | Erases all of the elements.
iterator find(const key_type& k) | Associative Container | Finds an element whose key is k.
const_iterator find(const key_type& k) const | Associative Container | Finds an element whose key is k.
size_type count(const key_type& k) | Unique Associative Container | Counts the number of elements whose key is k.
iterator lower_bound(const key_type& k) | Sorted Associative Container | Finds the first element whose key is not less than k.
const_iterator lower_bound(const key_type& k) const | Sorted Associative Container | Finds the first element whose key is not less than k.
iterator upper_bound(const key_type& k) | Sorted Associative Container | Finds the first element whose key greater than k.
const_iterator upper_bound(const key_type& k) const | Sorted Associative Container | Finds the first element whose key greater than k.
pair<iterator, iterator>
equal_range(const key_type& k)
Sorted Associative Container Finds a range containing all elements whose key is k.
pair<const_iterator, const_iterator>
equal_range(const key_type& k) const
Sorted Associative Container Finds a range containing all elements whose key is k.
data_type&
operator[](const key_type& k) [3]
map See below.
bool operator==(const map&,
                const map&)
Forward Container Tests two maps for equality. This is a global function, not a member function.
bool operator<(const map&,
               const map&)
Forward Container Lexicographical comparison. This is a global function, not a member function.

New members

These members are not defined in the Unique Sorted Associative Container and Pair Associative Container requirements, but are unique to map:
Member function Description
data_type&
operator[](const key_type& k) [3]
Returns a reference to the object that is associated with a particular key. If the map does not already contain such an object, operator[] inserts the default object data_type(). [3]

Notes

[1] Map::iterator is not a mutable iterator, because map::value_type is not Assignable. That is, if i is of type map::iterator and p is of type map::value_type, then *i = p is not a valid expression. However, map::iterator isn't a constant iterator either, because it can be used to modify the object that it points to. Using the same notation as above, (*i).second = p is a valid expression. The same point applies to map::reverse_iterator.

[2] This member function relies on member template functions, which at present (early 1998) are not supported by all compilers. If your compiler supports member templates, you can call this function with any type of input iterator. If your compiler does not yet support member templates, though, then the arguments must either be of type const value_type* or of type map::const_iterator.

[3] Since operator[] might insert a new element into the map, it can't possibly be a const member function. Note that the definition of operator[] is extremely simple: m[k] is equivalent to (*((m.insert(value_type(k, data_type()))).first)).second. Strictly speaking, this member function is unnecessary: it exists only for convenience.

See also

Associative Container, Sorted Associative Container, Pair Associative Container, Unique Sorted Associative Container, set multiset, multimap, hash_set, hash_map, hash_multiset, hash_multimap,


max

Categories: algorithms, utilities | Component type: function

Prototype

Max is an overloaded name; there are actually two max functions.
template <class T> const T& max(const T& a, const T& b);

template <class T, class BinaryPredicate>
const T& max(const T& a, const T& b, BinaryPredicate comp);

Description

Max returns the greater of its two arguments; it returns the first argument if neither is greater than the other.

The two versions of max differ in how they define whether one element is less than another. The first version compares objects using operator<, and the second compares objects using the function object comp.

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

For the first version:
  • T is a model of LessThan Comparable.
For the second version:
  • BinaryPredicate is a model of Binary Predicate.
  • T is convertible to BinaryPredicate's first argument type and to its second argument type.

Preconditions

Complexity

Example

const int x = max(3, 9);
assert(x == 9);

Notes

See also

min, min_element, max_element, LessThan Comparable


max_element

Category: algorithms | Component type: function

Prototype

Max_element is an overloaded name; there are actually two max_element functions.
template <class ForwardIterator>
ForwardIterator max_element(ForwardIterator first, ForwardIterator last);

template <class ForwardIterator, class BinaryPredicate>
ForwardIterator max_element(ForwardIterator first, ForwardIterator last,
                            BinaryPredicate comp);

Description

Max_element finds the largest element in the range [first, last). It returns the first iterator i in [first, last) such that no other iterator in [first, last) points to a value greater than *i. The return value is last if and only if [first, last) is an empty range.

The two versions of max_element differ in how they define whether one element is less than another. The first version compares objects using operator<, and the second compares objects using a function object comp.

The first version of max_element returns the first iterator i in [first, last) such that, for every iterator j in [first, last), *i < *j is false. The second version returns the first iterator i in [first, last) such that, for every iterator j in [first, last), comp(*i, *j) is false.

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

For the first version:
  • ForwardIterator is a model of Forward Iterator.
  • ForwardIterator's value type is LessThan Comparable.
For the second version:
  • ForwardIterator is a model of Forward Iterator.
  • BinaryPredicate is a model of Binary Predicate.
  • ForwardIterator's value type is convertible to BinaryPredicate's first argument type and second argument type.

Preconditions

  • [first, last) is a valid range.

Complexity

Linear. Zero comparisons if [first, last) is an empty range, otherwise exactly (last - first) - 1 comparisons.

Example

int main()
{
  list<int> L;
  generate_n(front_inserter(L), 1000, rand);

  list<int>::const_iterator it = max_element(L.begin(), L.end());
  cout << "The largest element is " << *it << endl;
}

Notes

See also

min, max, min_element, LessThan Comparable, sort, nth_element


mem_fun1_ref_t<Result, X, Arg>

Categories: functors, adaptors | Component type: type

Description

Mem_fun1_ref_t is an adaptor for member functions. If X is some class with a member function Result X::f(Arg) (that is, a member function that takes one argument of type Arg and that returns a value of type Result [1]), then a mem_fun1_ref_t<Result, X, Arg> is a function object adaptor that makes it possible to call f as if it were an ordinary function instead of a member function.

Mem_fun1_ref_t<Result, X, Arg>'s constructor takes a pointer to one of X's member functions. Then, like all function objects, mem_fun1_ref_t has an operator() that allows the mem_fun1_ref_t to be invoked with ordinary function call syntax. In this case, mem_fun1_ref_t's operator() takes two arguments; the first is of type X and the second is of type Arg.

If F is a mem_fun1_ref_t that was constructed to use the member function X::f, and if x is an object of type X and a is a value of type Arg, then the expression F(x, a) is equivalent to the expression x.f(a). The difference is simply that F can be passed to STL algorithms whose arguments must be function objects.

Mem_fun1_ref_t is one of a family of member function adaptors. These adaptors are useful if you want to combine generic programming with inheritance and polymorphism, since, in C++, polymorphism involves calling member functions through pointers or references. In fact, though, mem_fun1_ref_t is usually not as useful as mem_fun1_t. The difference between the two is that mem_fun1_t's first argument is a pointer to an object while mem_fun1_ref_t's argument is a reference to an object. References, unlike pointers, can't be stored in STL containers: pointers are objects in their own right, but references are merely aliases.

As with many other adaptors, it is usually inconvenient to use mem_fun1_ref_t's constructor directly. It is usually better to use the helper function mem_fun_ref [2] instead.

Example

Given a vector of vectors, extract one element from each vector.
int main() {
  int A1[5] = {1, 2, 3, 4, 5};
  int A2[5] = {1, 1, 2, 3, 5};
  int A3[5] = {1, 4, 1, 5, 9};

  vector<vector<int> > V;
  V.push_back(vector<int>(A1, A1 + 5));
  V.push_back(vector<int>(A2, A2 + 5));
  V.push_back(vector<int>(A3, A3 + 5));

  int indices[3] = {0, 2, 4};

  int& (vector<int>::*extract)(vector<int>::size_type);
  extract = vector<int>::operator[];
  transform(V.begin(), V.end(), indices,
            ostream_iterator<int>(cout, "\n"),
            mem_fun_ref(extract));
}

Definition

Defined in the standard header functional, and in the nonstandard backward-compatibility header function.h.

Template parameters

Parameter | Description | Default
Result | The member function's return type. |
X | The class whose member function the mem_fun1_ref_t invokes. |
Arg | The member function's argument type. |

Model of

Adaptable Binary Function

Type requirements

  • X has at least one member function that takes a single argument of type Arg and that returns a value of type Result. [1]

Public base classes

binary_function<X, Arg, Result>

Members

Member | Where defined | Description
first_argument_type | Adaptable Binary Function | The type of the first argument: X
second_argument_type | Adaptable Binary Function | The type of the second argument: Arg
result_type | Adaptable Binary Function | The type of the result: Result
Result operator()(X& x, Arg a) const
Binary Function Function call operator. Invokes x.f(a), where f is the member function that was passed to the constructor.
explicit mem_fun1_ref_t(Result (X::*f)(Arg))
mem_fun1_ref_t See below.
template <class Result, class X, class Arg>
mem_fun1_ref_t<Result, X, Arg>
mem_fun_ref(Result (X::*f)(Arg)); [2]
mem_fun1_ref_t See below.

New members

These members are not defined in the Adaptable Binary Function requirements, but are specific to mem_fun1_ref_t.
Member Description
explicit mem_fun1_ref_t(Result (X::*f)(Arg))
The constructor. Creates a mem_fun1_ref_t that calls the member function f.
template <class Result, class X, class Arg>
mem_fun1_ref_t<Result, X, Arg>
mem_fun1_ref(Result (X::*f)(Arg)); [2]
If f is of type Result (X::*)(Arg) then mem_fun_ref(f) is the same as mem_fun1_ref_t<Result, X, Arg>(f), but is more convenient. This is a global function, not a member function.

Notes

[1] The type Result is permitted to be void. That is, this adaptor may be used for functions that return no value. However, this presents implementation difficulties. According to the draft C++ standard, it is possible to return from a void function by writing return void instead of just return. At present, however (early 1998), very few compilers support that feature. As a substitute, then, mem_fun1_ref_t uses partial specialization to support void member functions. If your compiler has not implemented partial specialization, then you will not be able to use mem_fun1_ref_t with member functions whose return type is void.

[2] This helper function was called mem_fun1_ref in drafts of the C++ standard, but it is called mem_fun_ref in the final standard. This implementation provides both versions for backward compatibility, but mem_fun1_ref will be removed in a future release.

See also

mem_fun_t, mem_fun_ref_t, mem_fun1_t


mem_fun1_t<Result, X, Arg>

Categories: functors, adaptors | Component type: type

Description

Mem_fun1_t is an adaptor for member functions. If X is some class with a member function Result X::f(Arg) (that is, a member function that takes one argument of type Arg and that returns a value of type Result [1]), then a mem_fun1_t<Result, X, Arg> is a function object adaptor that makes it possible to call f as if it were an ordinary function instead of a member function.

Mem_fun1_t<Result, X, Arg>'s constructor takes a pointer to one of X's member functions. Then, like all function objects, mem_fun1_t has an operator() that allows the mem_fun1_t to be invoked with ordinary function call syntax. In this case, mem_fun1_t's operator() takes two arguments; the first is of type X* and the second is of type Arg.

If F is a mem_fun1_t that was constructed to use the member function X::f, and if x is a pointer of type X* and a is a value of type Arg, then the expression F(x, a) is equivalent to the expression x->f(a). The difference is simply that F can be passed to STL algorithms whose arguments must be function objects.

Mem_fun1_t is one of a family of member function adaptors. These adaptors are useful if you want to combine generic programming with inheritance and polymorphism, since, in C++, polymorphism involves calling member functions through pointers or references.

As with many other adaptors, it is usually inconvenient to use mem_fun1_t's constructor directly. It is usually better to use the helper function mem_fun [2] instead.

Example

struct Operation {
  virtual double eval(double) = 0;
};

struct Square : public Operation {
  double eval(double x) { return x * x; }
};

struct Negate : public Operation {
  double eval(double x) { return -x; }
};

int main() {
  vector<Operation*> operations;
  vector<double> operands;

  operations.push_back(new Square);
  operations.push_back(new Square);
  operations.push_back(new Negate);
  operations.push_back(new Negate);
  operations.push_back(new Square);

  operands.push_back(1);
  operands.push_back(2);
  operands.push_back(3);
  operands.push_back(4);
  operands.push_back(5);

  transform(operations.begin(), operations.end(),
            operands.begin(),
            ostream_iterator<double>(cout, "\n"),
            mem_fun(Operation::eval));
}

Definition

Defined in the standard header functional, and in the nonstandard backward-compatibility header function.h.

Template parameters

Parameter | Description | Default
Result | The member function's return type. |
X | The class whose member function the mem_fun1_t invokes. |
Arg | The member function's argument type. |

Model of

Adaptable Binary Function

Type requirements

  • X has at least one member function that takes a single argument of type Arg and that returns a value of type Result. [1]

Public base classes

binary_function<X*, Arg, Result>

Members

Member | Where defined | Description
first_argument_type | Adaptable Binary Function | The type of the first argument: X*
second_argument_type | Adaptable Binary Function | The type of the second argument: Arg
result_type | Adaptable Binary Function | The type of the result: Result
Result operator()(X* x, Arg a) const
Binary Function Function call operator. Invokes x->f(a), where f is the member function that was passed to the constructor.
explicit mem_fun1_t(Result (X::*f)(Arg))
mem_fun1_t See below.
template <class Result, class X, class Arg>
mem_fun1_t<Result, X, Arg>
mem_fun(Result (X::*f)(Arg)); [2]
mem_fun1_t See below.

New members

These members are not defined in the Adaptable Binary Function requirements, but are specific to mem_fun1_t.
Member Description
explicit mem_fun1_t(Result (X::*f)(Arg))
The constructor. Creates a mem_fun1_t that calls the member function f.
template <class Result, class X, class Arg>
mem_fun1_t<Result, X, Arg>
mem_fun(Result (X::*f)(Arg)); [2]
If f is of type Result (X::*)(Arg) then mem_fun(f) is the same as mem_fun1_t<Result, X, Arg>(f), but is more convenient. This is a global function, not a member function.

Notes

[1] The type Result is permitted to be void. That is, this adaptor may be used for functions that return no value. However, this presents implementation difficulties. According to the draft C++ standard, it is possible to return from a void function by writing return void instead of just return. At present, however (early 1998), very few compilers support that feature. As a substitute, then, mem_fun1_t uses partial specialization to support void member functions. If your compiler has not implemented partial specialization, then you will not be able to use mem_fun1_t with member functions whose return type is void.

[2] This helper function was called mem_fun1 in drafts of the C++ standard, but it is called mem_fun in the final standard. This implementation provides both versions for backward compatibility, but mem_fun1 will be removed in a future release.

See also

mem_fun_t, mem_fun_ref_t, mem_fun1_ref_t


mem_fun_ref_t<Result, X>

Categories: functors, adaptors | Component type: type

Description

Mem_fun_ref_t is an adaptor for member functions. If X is some class with a member function Result X::f() (that is, a member function that takes no arguments and that returns a value of type Result [1]), then a mem_fun_ref_t<Result, X> is a function object adaptor that makes it possible to call f() as if it were an ordinary function instead of a member function.

mem_fun_ref_t<Result, X>'s constructor takes a pointer to one of X's member functions. Then, like all function objects, mem_fun_ref_t has an operator() that allows the mem_fun_ref_t to be invoked with ordinary function call syntax. In this case, mem_fun_ref_t's operator() takes an argument of type X&.

If F is a mem_fun_ref_t that was constructed to use the member function X::f, and if x is of type X, then the expression F(x) is equivalent to the expression x.f(). The difference is simply that F can be passed to STL algorithms whose arguments must be function objects.

Mem_fun_ref_t is one of a family of member function adaptors. These adaptors are useful if you want to combine generic programming with inheritance and polymorphism, since, in C++, polymorphism involves calling member functions through pointers or references. In fact, though, mem_fun_ref_t is usually not as useful as mem_fun_t. The difference between the two is that mem_fun_t's argument is a pointer to an object while mem_fun_ref_t's argument is a reference to an object. References, unlike pointers, can't be stored in STL containers: pointers are objects in their own right, but references are merely aliases.

As with many other adaptors, it is usually inconvenient to use mem_fun_ref_t's constructor directly. It is usually better to use the helper function mem_fun_ref instead.

Example

struct B {
  virtual void print() = 0;
};

struct D1 : public B {
  void print() { cout << "I'm a D1" << endl; }
};

struct D2 : public B {
  void print() { cout << "I'm a D2" << endl; }
};

int main()
{
  vector<D1> V;

  V.push_back(D1());
  V.push_back(D1());

  for_each(V.begin(), V.end(), mem_fun_ref(B::print));
}

Definition

Defined in the standard header functional, and in the nonstandard backward-compatibility header function.h.

Template parameters

Parameter | Description | Default
Result | The member function's return type. |
X | The class whose member function the mem_fun_ref_t invokes. |

Model of

Adaptable Unary Function

Type requirements

  • X has at least one member function that takes no arguments and that returns a value of type Result. [1]

Public base classes

unary_function<X, Result>

Members

Member | Where defined | Description
argument_type | Adaptable Unary Function | The type of the argument: X
result_type | Adaptable Unary Function | The type of the result: Result
Result operator()(X& x) const
Unary Function Function call operator. Invokes x.f(), where f is the member function that was passed to the constructor.
explicit mem_fun_ref_t(Result (X::*f)())
mem_fun_ref_t See below.
template <class Result, class X>
mem_fun_ref_t<Result, X>
mem_fun_ref(Result (X::*f)());
mem_fun_ref_t See below.

New members

These members are not defined in the Adaptable Unary Function requirements, but are specific to mem_fun_ref_t.
Member Description
explicit mem_fun_ref_t(Result (X::*f)())
The constructor. Creates a mem_fun_ref_t that calls the member function f.
template <class Result, class X>
mem_fun_ref_t<Result, X>
mem_fun_ref(Result (X::*f)());
If f is of type Result (X::*)() then mem_fun_ref(f) is the same as mem_fun_ref_t<Result, X>(f), but is more convenient. This is a global function, not a member function.

Notes

[1] The type Result is permitted to be void. That is, this adaptor may be used for functions that return no value. However, this presents implementation difficulties. According to the draft C++ standard, it is possible to return from a void function by writing return void instead of just return. At present, however (early 1998), very few compilers support that feature. As a substitute, then, mem_fun_ref_t uses partial specialization to support void member functions. If your compiler has not implemented partial specialization, then you will not be able to use mem_fun_ref_t with member functions whose return type is void.

See also

mem_fun_t, mem_fun1_t, mem_fun1_ref_t


mem_fun_t<Result, X>

Categories: functors, adaptors | Component type: type

Description

Mem_fun_t is an adaptor for member functions. If X is some class with a member function Result X::f() (that is, a member function that takes no arguments and that returns a value of type Result [1]), then a mem_fun_t<Result, X> is a function object adaptor that makes it possible to call f() as if it were an ordinary function instead of a member function.

Mem_fun_t<Result, X>'s constructor takes a pointer to one of X's member functions. Then, like all function objects, mem_fun_t has an operator() that allows the mem_fun_t to be invoked with ordinary function call syntax. In this case, mem_fun_t's operator() takes an argument of type X*.

If F is a mem_fun_t that was constructed to use the member function X::f, and if x is a pointer of type X*, then the expression F(x) is equivalent to the expression x->f(). The difference is simply that F can be passed to STL algorithms whose arguments must be function objects.

Mem_fun_t is one of a family of member function adaptors. These adaptors are useful if you want to combine generic programming with inheritance and polymorphism, since, in C++, polymorphism involves calling member functions through pointers or references.

As with many other adaptors, it is usually inconvenient to use mem_fun_t's constructor directly. It is usually better to use the helper function mem_fun instead.

Example

struct B {
  virtual void print() = 0;
};

struct D1 : public B {
  void print() { cout << "I'm a D1" << endl; }
};

struct D2 : public B {
  void print() { cout << "I'm a D2" << endl; }
};

int main()
{
  vector<B*> V;

  V.push_back(new D1);
  V.push_back(new D2);
  V.push_back(new D2);
  V.push_back(new D1);

  for_each(V.begin(), V.end(), mem_fun(&B::print));
}

Definition

Defined in the standard header functional, and in the nonstandard backward-compatibility header function.h.

Template parameters

Parameter | Description | Default
Result | The member function's return type. |
X | The class whose member function the mem_fun_t invokes. |

Model of

Adaptable Unary Function

Type requirements

  • X has at least one member function that takes no arguments and that returns a value of type Result. [1]

Public base classes

unary_function<X*, Result>

Members

Member | Where defined | Description
argument_type | Adaptable Unary Function | The type of the argument: X*
result_type | Adaptable Unary Function | The type of the result: Result
Result operator()(X* x) const
Unary Function Function call operator. Invokes x->f(), where f is the member function that was passed to the constructor.
explicit mem_fun_t(Result (X::*f)())
mem_fun_t See below.
template <class Result, class X>
mem_fun_t<Result, X>
mem_fun(Result (X::*f)());
mem_fun_t See below.

New members

These members are not defined in the Adaptable Unary Function requirements, but are specific to mem_fun_t.
Member Description
explicit mem_fun_t(Result (X::*f)())
The constructor. Creates a mem_fun_t that calls the member function f.
template <class Result, class X>
mem_fun_t<Result, X>
mem_fun(Result (X::*f)());
If f if of type Result (X::*) then mem_fun(f) is the same as mem_fun_t<Result, X>(f), but is more convenient. This is a global function, not a member function.

Notes

[1] The type Result is permitted to be void. That is, this adaptor may be used for functions that return no value. However, this presents implementation difficulties. According to the draft C++ standard, it is possible to return from a void function by writing return void instead of just return. At present, however (early 1998), very few compilers support that feature. As a substitute, then, mem_fun_t uses partial specialization to support void member functions. If your compiler has not implemented partial specialization, then you will not be able to use mem_fun_t with member functions whose return type is void.

See also

mem_fun_ref_t, mem_fun1_t, mem_fun1_ref_t


merge

Category: algorithms | Component type: function

Prototype

Merge is an overloaded name: there are actually two merge functions.
template <class InputIterator1, class InputIterator2, class OutputIterator>
OutputIterator merge(InputIterator1 first1, InputIterator1 last1,
                     InputIterator2 first2, InputIterator2 last2,
                     OutputIterator result);

template <class InputIterator1, class InputIterator2, class OutputIterator,
          class StrictWeakOrdering>
OutputIterator merge(InputIterator1 first1, InputIterator1 last1,
                     InputIterator2 first2, InputIterator2 last2,
                     OutputIterator result, StrictWeakOrdering comp);

Description

Merge combines two sorted ranges [first1, last1) and [first2, last2) into a single sorted range. That is, it copies elements from [first1, last1) and [first2, last2) into [result, result + (last1 - first1) + (last2 - first2)) such that the resulting range is in ascending order. Merge is stable, meaning both that the relative order of elements within each input range is preserved, and that for equivalent [1] elements in both input ranges the element from the first range precedes the element from the second. The return value is result + (last1 - first1) + (last2 - first2).

The two versions of merge differ in how elements are compared. The first version uses operator<. That is, the input ranges and the output range satisfy the condition that for every pair of iterators i and j such that i precedes j, *j < *i is false. The second version uses the function object comp. That is, the input ranges and the output range satisfy the condition that for every pair of iterators i and j such that i precedes j, comp(*j, *i) is false.

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

For the first version:
  • InputIterator1 is a model of Input Iterator.
  • InputIterator2 is a model of Input Iterator.
  • InputIterator1's value type is the same type as InputIterator2's value type.
  • InputIterator1's value type is a model of LessThan Comparable.
  • The ordering on objects of InputIterator1's value type is a strict weak ordering, as defined in the LessThan Comparable requirements.
  • InputIterator1's value type is convertible to a type in OutputIterator's set of value types.
For the second version:
  • InputIterator1 is a model of Input Iterator.
  • InputIterator2 is a model of Input Iterator.
  • InputIterator1's value type is the same type as InputIterator2's value type.
  • StrictWeakOrdering is a model of Strict Weak Ordering.
  • InputIterator1's value type is convertible to StrictWeakOrdering's argument type.
  • InputIterator1's value type is convertible to a type in OutputIterator's set of value types.

Preconditions

For the first version:
  • [first1, last1) is a valid range.
  • [first1, last1) is in ascending order. That is, for every pair of iterators i and j in [first1, last1) such that i precedes j, *j < *i is false.
  • [first2, last2) is a valid range.
  • [first2, last2) is in ascending order. That is, for every pair of iterators i and j in [first2, last2) such that i precedes j, *j < *i is false.
  • The ranges [first1, last1) and [result, result + (last1 - first1) + (last2 - first2)) do not overlap.
  • The ranges [first2, last2) and [result, result + (last1 - first1) + (last2 - first2)) do not overlap.
  • There is enough space to hold all of the elements being copied. More formally, the requirement is that [result, result + (last1 - first1) + (last2 - first2)) is a valid range.
For the second version:
  • [first1, last1) is a valid range.
  • [first1, last1) is in ascending order. That is, for every pair of iterators i and j in [first1, last1) such that i precedes j, comp(*j, *i) is false.
  • [first2, last2) is a valid range.
  • [first2, last2) is in ascending order. That is, for every pair of iterators i and j in [first2, last2) such that i precedes j, comp(*j, *i) is false.
  • The ranges [first1, last1) and [result, result + (last1 - first1) + (last2 - first2)) do not overlap.
  • The ranges [first2, last2) and [result, result + (last1 - first1) + (last2 - first2)) do not overlap.
  • There is enough space to hold all of the elements being copied. More formally, the requirement is that [result, result + (last1 - first1) + (last2 - first2)) is a valid range.

Complexity

Linear. No comparisons if both [first1, last1) and [first2, last2) are empty ranges, otherwise at most (last1 - first1) + (last2 - first2) - 1 comparisons.

Example

int main()
{
  int A1[] = { 1, 3, 5, 7 };
  int A2[] = { 2, 4, 6, 8 };
  const int N1 = sizeof(A1) / sizeof(int);
  const int N2 = sizeof(A2) / sizeof(int);

  merge(A1, A1 + N1, A2, A2 + N2,
        ostream_iterator<int>(cout, " "));
  // The output is "1 2 3 4 5 6 7 8"
}

Notes

[1] Note that you may use an ordering that is a strict weak ordering but not a total ordering; that is, there might be values x and y such that x < y, x > y, and x == y are all false. (See the LessThan Comparable requirements for a more complete discussion.) Two elements x and y are equivalent if neither x < y nor y < x. If you're using a total ordering, however (if you're using strcmp, for example, or if you're using ordinary arithmetic comparison on integers), then you can ignore this technical distinction: for a total ordering, equality and equivalence are the same.

See also

inplace_merge, set_union, sort


min

Categories: algorithms, utilities | Component type: function

Prototype

Min is an overloaded name; there are actually two min functions.
template <class T> const T& min(const T& a, const T& b);

template <class T, class BinaryPredicate>
const T& min(const T& a, const T& b, BinaryPredicate comp);

Description

Min returns the lesser of its two arguments; it returns the first argument if neither is less than the other.

The two versions of min differ in how they define whether one element is less than another. The first version compares objects using operator<, and the second compares objects using the function object comp.

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

For the first version:
  • T is a model of LessThan Comparable.
For the second version:
  • BinaryPredicate is a model of Binary Predicate.
  • T is convertible to BinaryPredicate's first argument type and to its second argument type.

Preconditions

Complexity

Example

const int x = min(3, 9);
assert(x == 3);

Notes

See also

max, min_element, max_element, LessThan Comparable


minus<T>

Category: functors | Component type: type

Description

Minus<T> is a function object. Specifically, it is an Adaptable Binary Function. If f is an object of class minus<T> and x and y are objects of class T, then f(x,y) returns x-y.

Example

Each element in V3 will be the difference of the corresponding elements in V1 and V2
const int N = 1000;
vector<double> V1(N);
vector<double> V2(N);
vector<double> V3(N);

iota(V1.begin(), V1.end(), 1);
fill(V2.begin(), V2.end(), 75);

assert(V2.size() >= V1.size() && V3.size() >= V1.size());
transform(V1.begin(), V1.end(), V2.begin(), V3.begin(),
          minus<double>());

Definition

Defined in the standard header functional, and in the nonstandard backward-compatibility header function.h.

Template parameters

Parameter | Description | Default
T | The function object's argument type and result type. |

Model of

Adaptable Binary Function, Default Constructible

Type requirements

T must be a numeric type; if x and y are objects of type T, then x-y must be defined and must have a return type that is convertible to T. T must be Assignable.

Public base classes

binary_function<T, T, T>

Members

Member | Where defined | Description
first_argument_type | Adaptable Binary Function | The type of the first argument: T
second_argument_type | Adaptable Binary Function | The type of the second argument: T
result_type | Adaptable Binary Function | The type of the result: T
T operator()(const T& x, const T& y) | Adaptable Binary Function | Function call operator. The return value is x - y.
minus() | Default Constructible | The default constructor.

New members

All of minus's members are defined in the Adaptable Binary Function and Default Constructible requirements. Minus does not introduce any new members.

Notes

See also

The Function Object overview, Adaptable Binary Function, binary_function, plus, multiplies, divides, modulus, negate


min_element

Category: algorithms | Component type: function

Prototype

Min_element is an overloaded name; there are actually two min_element functions.
template <class ForwardIterator>
ForwardIterator min_element(ForwardIterator first, ForwardIterator last);

template <class ForwardIterator, class BinaryPredicate>
ForwardIterator min_element(ForwardIterator first, ForwardIterator last,
                            BinaryPredicate comp);

Description

Min_element finds the smallest element in the range [first, last). It returns the first iterator i in [first, last) such that no other iterator in [first, last) points to a value smaller than *i. The return value is last if and only if [first, last) is an empty range.

The two versions of min_element differ in how they define whether one element is less than another. The first version compares objects using operator<, and the second compares objects using a function object comp.

The first version of min_element returns the first iterator i in [first, last) such that, for every iterator j in [first, last), *j < *i is false. The second version returns the first iterator i in [first, last) such that, for every iterator j in [first, last), comp(*j, *i) is false.

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

For the first version:
  • ForwardIterator is a model of Forward Iterator.
  • ForwardIterator's value type is LessThan Comparable.
For the second version:
  • ForwardIterator is a model of Forward Iterator.
  • BinaryPredicate is a model of Binary Predicate.
  • ForwardIterator's value type is convertible to BinaryPredicate's first argument type and second argument type.

Preconditions

  • [first, last) is a valid range.

Complexity

Linear. Zero comparisons if [first, last) is an empty range, otherwise exactly (last - first) - 1 comparisons.

Example

int main()
{
  list<int> L;
  generate_n(front_inserter(L), 1000, rand);

  list<int>::const_iterator it = min_element(L.begin(), L.end());
  cout << "The smallest element is " << *it << endl;
}

Notes

See also

min, max, max_element, LessThan Comparable, sort, nth_element


mismatch

Category: algorithms | Component type: function

Prototype

Mismatch is an overloaded name; there are actually two mismatch functions.
template <class InputIterator1, class InputIterator2>
pair<InputIterator1, InputIterator2>
mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2);

template <class InputIterator1, class InputIterator2,
          class BinaryPredicate>
pair<InputIterator1, InputIterator2>
mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2,
         BinaryPredicate binary_pred);

Description

Mismatch finds the first position where the two ranges [first1, last1) and [first2, first2 + (last1 - first1)) differ. The two versions of mismatch use different tests for whether elements differ.

The first version of mismatch finds the first iterator i in [first1, last1) such that *i != *(first2 + (i - first1)). The return value is a pair whose first element is i and whose second element is *(first2 + (i - first1)). If no such iterator i exists, the return value is a pair whose first element is last1 and whose second element is *(first2 + (last1 - first1)).

The second version of mismatch finds the first iterator i in [first1, last1) such that binary_pred(*i, *(first2 + (i - first1)) is false. The return value is a pair whose first element is i and whose second element is *(first2 + (i - first1)). If no such iterator i exists, the return value is a pair whose first element is last1 and whose second element is *(first2 + (last1 - first1)).

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

For the first version:
  • InputIterator1 is a model of Input Iterator.
  • InputIterator2 is a model of Input Iterator.
  • InputIterator1's value type is a model of Equality Comparable.
  • InputIterator2's value type is a model of Equality Comparable.
  • InputIterator1's value type can be compared for equality with InputIterator2's value type.
For the second version:
  • InputIterator1 is a model of Input Iterator.
  • InputIterator2 is a model of Input Iterator.
  • BinaryPredicate is a model of Binary Predicate.
  • InputIterator1's value type is convertible to BinaryPredicate's first argument type.
  • InputIterator2's value type is convertible to BinaryPredicate's second argument type.

Preconditions

  • [first1, last1) is a valid range.
  • [first2, first2 + (last2 - last1)) is a valid range.

Complexity

Linear. At most last1 - first1 comparisons.

Example

int A1[] = { 3, 1, 4, 1, 5, 9, 3 };
int A2[] = { 3, 1, 4, 2, 8, 5, 7 };
const int N = sizeof(A1) / sizeof(int);

pair<int*, int*> result = mismatch(A1, A1 + N, A2);
cout << "The first mismatch is in position " << result.first - A1 << endl;
cout << "Values are: " << *(result.first) << ", " << *(result.second) << endl;

Notes

See also

equal, search, find, find_if


modulus<T>

Category: functors | Component type: type

Description

Modulus<T> is a function object. Specifically, it is an Adaptable Binary Function. If f is an object of class modulus<T> and x and y are objects of class T, then f(x,y) returns x%y.

Example

Each element in V3 will be the modulus of the corresponding elements in V1 and V2
const int N = 1000;
vector<double> V1(N);
vector<double> V2(N);
vector<double> V3(N);

iota(V1.begin(), V1.end(), 1);
fill(V2.begin(), V2.end(), 75);

assert(V2.size() >= V1.size() && V3.size() >= V1.size());
transform(V1.begin(), V1.end(), V2.begin(), V3.begin(),
          modulus<int>());

Definition

Defined in the standard header functional, and in the nonstandard backward-compatibility header function.h.

Template parameters

Parameter | Description | Default
T | The function object's argument type and result type. |

Model of

Adaptable Binary Function, Default Constructible

Type requirements

T must be an integral type; if x and y are objects of type T, then x%y must be defined and must have a return type that is convertible to T. T must be Assignable.

Public base classes

binary_function<T, T, T>

Members

Member | Where defined | Description
first_argument_type | Adaptable Binary Function | The type of the first argument: T
second_argument_type | Adaptable Binary Function | The type of the second argument: T
result_type | Adaptable Binary Function | The type of the result: T
T operator()(const T& x, const T& y) | Adaptable Binary Function | Function call operator. The return value is x % y.
modulus() | Default Constructible | The default constructor.

New members

All of modulus's members are defined in the Adaptable Binary Function and Default Constructible requirements. Modulus does not introduce any new members.

Notes

See also

The Function Object overview, Adaptable Binary Function, binary_function, plus, minus, multiplies, divides, negate


MonoidOperation

Category: functors | Component type: concept

Description

A Monoid Operation is a special sort of Binary Function. A Binary Function must satisfy three conditions in order to be a Monoid Operation. First, its first argument type and second argument type must be the same, and its result type must be the same as its argument type. Second, there must be an identity element. Third, the operation must be associative. Examples of Monoid Operations are addition and multiplication. [1]

Refinement of

Binary Function

Associated types

Argument type The type of the Monoid Operation's first argument and second argument, and also the type returned when the Monoid Operation is returned.

Notation

F | A type that is a model of MonoidOperation
T | F's argument type.
f | Object of type F
x, y, z | Objects of type T

Definitions

A type F that is a model of binary function is associative if F's first argument type, second argument type, and result type are the same, and if, for every object f of type F and for every objects x, y, and z of F's argument type, f(x, f(y, z)) is the same as f(f(x, y), z). [2]

Valid Expressions

In addition to the expressions described in the Binary Function requirements, the following expressions must be valid.
Name | Expression | Type requirements | Return type
Function call | f(x, y) |  | T
Identity element | identity_element(f) [3] |  | T

Expression semantics

Name | Expression | Precondition | Semantics | Postcondition
Function call | f(x, y) | x and y are in the domain of f. | Calls f with x and y as arguments. |
Identity element | identity_element(f) |  | Returns the monoid's identity element. That is, the return value is a value id of type T such that, for all x in the domain of f, f(x, id) and f(id, x) both return x. |

Complexity guarantees

Invariants

Associativity | For any x, y, and z of type T, f(x, f(y, z)) and f(f(x, y), z) return the same value. [4]
Identity element. | There exists some element id of type T such that, for all x of type T, f(x, id) and f(id, x) both return x. The expression identity_element(f) returns id.

Models

  • plus<int>
  • multiplies<double>

Notes

[1] A monoid is one of three closely related algebraic structures. A semigroup is a set S, and a binary operation *, with the properties that * is closed on S (that is, if x and y are elements of S then x * y is also a member of S) and that * is associative (that is, if x, y, and z are elements of S, then x * (y * z) = (x * y) * z). A monoid is a semigroup that has an identity element. That is, there exists some element id such that, for all x in S, x * id = id * x = x. Finally, a group is a monoid with the property that every element has an inverse. That is, for every x in S, there exists an element xi such that x * xi = xi * x = id. As an example, the set of real numbers under multiplication is a monoid (the identity element is 1), but it isn't a group. It isn't a group because 0 has no inverse.

[2] Mathematics textbooks typically write this as an equation, instead of using words like "is the same as". We can't use equality in this definition, however, because F's argument type might not be equality comparable. If F's argument type is equality comparable, however, then these two expression are expected to be equal: the condition of associativity becomes f(x, f(y, z)) == f(f(x, y), z)

[3] This is implemented as an overloaded function. The function identity_element is defined, in the standard header functional, and the nonstandard backward-compatibility header function.h, for arguments of type plus<T> and multiplies<T>. If you define a new Monoid Operation F (matrix multiplication, for example), you must overload identity_element for arguments of type F. The identity_element function is an SGI extension; it is not part of the C++ standard.

[4] Associativity is not the same as commutativity. That is, the requirement that x * (y * z) == (x * y) * z is completely unrelated to the requirement that x * y == y * x. Monoid operations are required to be associative, but they are not required to be commutative. As an example, square matrices under multiplication form a monoid even though matrix multiplication is not commutative.

See also

Binary Function, plus, multiplies


multimap<Key, Data, Compare, Alloc>

Category: containers | Component type: type

Description

Multimap is a Sorted Associative Container that associates objects of type Key with objects of type Data. multimap is a Pair Associative Container, meaning that its value type is pair<const Key, Data>. It is also a Multiple Associative Container, meaning that there is no limit on the number of elements with the same key.

Multimap has the important property that inserting a new element into a multimap does not invalidate iterators that point to existing elements. Erasing an element from a multimap also does not invalidate any iterators, except, of course, for iterators that actually point to the element that is being erased.

Example

struct ltstr
{
  bool operator()(const char* s1, const char* s2) const
  {
    return strcmp(s1, s2) < 0;
  }
};

int main()
{
  multimap<const char*, int, ltstr> m;

  m.insert(pair<const char* const, int>("a", 1));
  m.insert(pair<const char* const, int>("c", 2));
  m.insert(pair<const char* const, int>("b", 3));
  m.insert(pair<const char* const, int>("b", 4));
  m.insert(pair<const char* const, int>("a", 5));
  m.insert(pair<const char* const, int>("b", 6));

  cout << "Number of elements with key a: " << m.count("a") << endl;
  cout << "Number of elements with key b: " << m.count("b") << endl;
  cout << "Number of elements with key c: " << m.count("c") << endl;

  cout << "Elements in m: " << endl;
  for (multimap<const char*, int, ltstr>::iterator it = m.begin();
       it != m.end();
       ++it)
   cout << "  [" << (*it).first << ", " << (*it).second << "]" << endl;
}

Definition

Defined in the standard header map, and in the nonstandard backward-compatibility header multimap.h.

Template parameters

Parameter | Description | Default
Key | The multimap's key type. This is also defined as multimap::key_type. |
Data | The multimap's data type. This is also defined as multimap::data_type. |
Compare | The key comparison function, a Strict Weak Ordering whose argument type is key_type; it returns true if its first argument is less than its second argument, and false otherwise. This is also defined as multimap::key_compare. | less<Key>
Alloc | The multimap's allocator, used for all internal memory management. | alloc

Model of

Multiple Sorted Associative Container, Pair Associative Container

Type requirements

  • Data is Assignable.
  • Compare is a Strict Weak Ordering whose argument type is Key.
  • Alloc is an Allocator.

Public base classes

None.

Members

Member | Where defined | Description
key_type | Associative Container | The multimap's key type, Key.
data_type | Pair Associative Container | The type of object associated with the keys.
value_type | Pair Associative Container | The type of object, pair<const key_type, data_type>, stored in the multimap.
key_compare | Sorted Associative Container | Function object that compares two keys for ordering.
value_compare | Sorted Associative Container | Function object that compares two values for ordering.
pointer | Container | Pointer to T.
reference | Container | Reference to T
const_reference | Container | Const reference to T
size_type | Container | An unsigned integral type.
difference_type | Container | A signed integral type.
iterator | Container | Iterator used to iterate through a multimap. [1]
const_iterator | Container | Const iterator used to iterate through a multimap.
reverse_iterator | Reversible Container | Iterator used to iterate backwards through a multimap. [1]
const_reverse_iterator | Reversible Container | Const iterator used to iterate backwards through a multimap.
iterator begin() | Container | Returns an iterator pointing to the beginning of the multimap.
iterator end() | Container | Returns an iterator pointing to the end of the multimap.
const_iterator begin() const | Container | Returns a const_iterator pointing to the beginning of the multimap.
const_iterator end() const | Container | Returns a const_iterator pointing to the end of the multimap.
reverse_iterator rbegin() | Reversible Container | Returns a reverse_iterator pointing to the beginning of the reversed multimap.
reverse_iterator rend() | Reversible Container | Returns a reverse_iterator pointing to the end of the reversed multimap.
const_reverse_iterator rbegin() const | Reversible Container | Returns a const_reverse_iterator pointing to the beginning of the reversed multimap.
const_reverse_iterator rend() const | Reversible Container | Returns a const_reverse_iterator pointing to the end of the reversed multimap.
size_type size() const | Container | Returns the size of the multimap.
size_type max_size() const | Container | Returns the largest possible size of the multimap.
bool empty() const | Container | true if the multimap's size is 0.
key_compare key_comp() const | Sorted Associative Container | Returns the key_compare object used by the multimap.
value_compare value_comp() const | Sorted Associative Container | Returns the value_compare object used by the multimap.
multimap() | Container | Creates an empty multimap.
multimap(const key_compare& comp) | Sorted Associative Container | Creates an empty multimap, using comp as the key_compare object.
template <class InputIterator>
multimap(InputIterator f, InputIterator l)
[2]
Multiple Sorted Associative Container Creates a multimap with a copy of a range.
template <class InputIterator>
multimap(InputIterator f, InputIterator l,
         const key_compare& comp)
[2]
Multiple Sorted Associative Container Creates a multimap with a copy of a range, using comp as the key_compare object.
multimap(const multimap&) | Container | The copy constructor.
multimap& operator=(const multimap&) | Container | The assignment operator
void swap(multimap&) | Container | Swaps the contents of two multimaps.
iterator insert(const value_type& x) | Multiple Associative Container | Inserts x into the multimap.
iterator insert(iterator pos,
                const value_type& x)
Multiple Sorted Associative Container Inserts x into the multimap, using pos as a hint to where it will be inserted.
template <class InputIterator>
void insert(InputIterator, InputIterator)
[2]
Multiple Sorted Associative Container Inserts a range into the multimap.
void erase(iterator pos) | Associative Container | Erases the element pointed to by pos.
size_type erase(const key_type& k) | Associative Container | Erases the element whose key is k.
void erase(iterator first, iterator last) | Associative Container | Erases all elements in a range.
void clear() | Associative Container | Erases all of the elements.
iterator find(const key_type& k) | Associative Container | Finds an element whose key is k.
const_iterator find(const key_type& k) const | Associative Container | Finds an element whose key is k.
size_type count(const key_type& k) | Associative Container | Counts the number of elements whose key is k.
iterator lower_bound(const key_type& k) | Sorted Associative Container | Finds the first element whose key is not less than k.
const_iterator lower_bound(const key_type& k) const | Sorted Associative Container | Finds the first element whose key is not less than k.
iterator upper_bound(const key_type& k) | Sorted Associative Container | Finds the first element whose key greater than k.
const_iterator upper_bound(const key_type& k) const | Sorted Associative Container | Finds the first element whose key greater than k.
pair<iterator, iterator>
equal_range(const key_type& k)
Sorted Associative Container Finds a range containing all elements whose key is k.
pair<const_iterator, const_iterator>
equal_range(const key_type& k) const
Sorted Associative Container Finds a range containing all elements whose key is k.
bool operator==(const multimap&,
                const multimap&)
Forward Container Tests two multimaps for equality. This is a global function, not a member function.
bool operator<(const multimap&,
               const multimap&)
Forward Container Lexicographical comparison. This is a global function, not a member function.

New members

All of multimap's members are defined in the Multiple Sorted Associative Container and Pair Associative Container requirements. Multimap does not introduce any new members.

Notes

[1] Multimap::iterator is not a mutable iterator, because multimap::value_type is not Assignable. That is, if i is of type multimap::iterator and p is of type multimap::value_type, then *i = p is not a valid expression. However, multimap::iterator isn't a constant iterator either, because it can be used to modify the object that it points to. Using the same notation as above, (*i).second = p is a valid expression. The same point applies to multimap::reverse_iterator.

[2] This member function relies on member template functions, which at present (early 1998) are not supported by all compilers. If your compiler supports member templates, you can call this function with any type of input iterator. If your compiler does not yet support member templates, though, then the arguments must either be of type const value_type* or of type multimap::const_iterator.

See also

Associative Container, Sorted Associative Container, Pair Associative Container, Multiple Sorted Associative Container, set, map multiset, hash_set, hash_map, hash_multiset, hash_multimap


Multiple Associative Container

Category: containers | Component type: concept

Description

A Multiple Associative Container is an Associative Container in which there may be more than one element with the same key. That is, it is an Associative Container that does not have the restrictions of a Unique Associative Container.

Refinement of

Associative Container

Associated types

None, except for those defined by Associative Container

Notation

X | A type that is a model of Multiple Associative Container
a | Object of type X
t | Object of type X::value_type
k | Object of type X::key_type
p, q | Object of type X::iterator

Definitions

Valid expressions

In addition to the expressions defined in Associative Container, the following expressions must be valid.
Name | Expression | Type requirements | Return type
Range constructor
X(i, j)
X a(i, j);
i and j are Input Iterators whose value type is convertible to T [1]
Insert element | a.insert(t) | X::iterator
Insert range | a.insert(i, j) | i and j are Input Iterators whose value type is convertible to X::value_type. | void

Expression semantics

Name | Expression | Precondition | Semantics | Postcondition
Range constructor
X(i, j)
X a(i, j);
[i,j) is a valid range. Creates an associative container that contains all elements in the range [i,j). size() is equal to the distance from i to j. Each element in [i, j) is present in the container.
Insert element | a.insert(t) | Inserts t into a. | The size of a is incremented by 1. The value of a.count(t) is incremented by a.
Insert range | a.insert(i, j) | [i, j) is a valid range. | Equivalent to a.insert(t) for each object t that is pointed to by an iterator in the range [i, j). Each element is inserted into a. | The size of a is incremented by j - i.

Complexity guarantees

Average complexity for insert element is at most logarithmic.

Average complexity for insert range is at most O(N * log(size() + N)), where N is j - i.

Invariants

Models

  • multiset
  • multimap
  • hash_multiset
  • hash_multimap

Notes

[1] At present (early 1998), not all compilers support "member templates". If your compiler supports member templates then i and j may be of any type that conforms to the Input Iterator requirements. If your compiler does not yet support member templates, however, then i and j must be of type const T* or of type X::const_iterator.

See also

Associative Container, Unique Associative Container, Unique Sorted Associative Container, Multiple Sorted Associative Container


Multiple Hashed Associative Container

Category: containers | Component type: concept

Description

A Multiple Hashed Associative Container is a Hashed Associative Container that is also a Multiple Associative Container. That is, it is a Hashed Associative Container with the property that any number of elements in the container may have the same key

Refinement of

Hashed Associative Container, Multiple Associative Container

Associated types

None, except for those described in the Hashed Associative Container and Multiple Associative Container requirements.

Notation

X | A type that is a model of Hashed Associative Container
a | Object of type X
t | Object of type X::value_type
k | Object of type X::key_type
p, q | Object of type X::iterator
n | Object of type X::size_type
h | Object of type X::hasher
c | Object of type X::key_equal

Definitions

Valid expressions

In addition to the expressions defined in Hashed Associative Container and and Multiple Associative Container, the following expressions must be valid.
Name Expression Type requirements Return type
Range constructor
X(i, j)
X a(i, j);
i and j are Input Iterators whose value type is convertible to T [1]. X
Range constructor with bucket count
X(i, j, n)
X a(i, j, n);
i and j are Input Iterators whose value type is convertible to T [1]. X
Range constructor with hash function
X(i, j, n, h)
X a(i, j, n, h);
i and j are Input Iterators whose value type is convertible to T [1]. X
Range constructor with key equal
X(i, j, n, h, k)
X a(i, j, n, h, k);
i and j are Input Iterators whose value type is convertible to T [1]. X

Expression semantics

Name Expression Precondition Semantics Postcondition
Range constructor
X(i, j)
X a(i, j);
[i,j) is a valid range. Creates an associative container that contains all elements in the range [i,j), using hasher() as the hash function and key_equal() as the key equality function. size() is equal to the distance from i to j. The bucket count is an unspecified default value. The hash function is hasher(), and the key equality function is key_equal().
Range constructor with bucket count
X(i, j, n)
X a(i, j, n);
[i,j) is a valid range. Creates an associative container that contains all elements in the range [i,j), using at least n buckets, and using hasher() as the hash function and key_equal() as the key equality function. size() is equal to the distance from i to j. The bucket count is greater than or equal to n. The hash function is hasher(), and the key equality function is key_equal().
Range constructor with hash function
X(i, j, n, h)
X a(i, j, n, h);
[i,j) is a valid range. Creates an associative container that contains all elements in the range [i,j), using at least n buckets, and using h as the hash function and key_equal() as the key equality function. size() is equal to the distance from i to j. The bucket count is greater than or equal to n. The hash function is h, and the key equality function is key_equal().
Range constructor with key equal
X(i, j, n, h, k)
X a(i, j, n, h, k);
[i,j) is a valid range. Creates an associative container that contains all elements in the range [i,j), using at least n buckets, and using h as the hash function and k as the key equality function. size() is equal to the distance from i to j. The bucket count is greater than or equal to n. The hash function is h, and the key equality function is k.

Complexity guarantees

The range constructor, range constructor with bucket count, range constructor with hash function, and range constructor with key equal, are all linear in j - i.

Invariants

Models

  • hash_multiset
  • hash_multimap

Notes

[1] At present (early 1998), not all compilers support "member templates". If your compiler supports member templates then i and j may be of any type that conforms to the Input Iterator requirements. If your compiler does not yet support member templates, however, then i and j must be of type const T* or of type X::const_iterator.

See also

Associative Container, Hashed Associative Container, Unique Hashed Associative Container Sorted Associative Container


Multiple Sorted Associative Container

Category: containers | Component type: concept

Description

A Multiple Sorted Associative Container is a Sorted Associative Container that is also a Multiple Associative Container. That is, it is a Sorted Associative Container with the property that any number of elements in the container may have equivalent keys.

Refinement of

Sorted Associative Container, Multiple Associative Container

Associated types

None, except for those described in the Sorted Associative Container and Multiple Associative Container requirements.

Notation

X | A type that is a model of Multiple Sorted Associative Container
a | Object of type X
t | Object of type X::value_type
k | Object of type X::key_type
p, q | Object of type X::iterator
c | Object of type X::key_compare

Definitions

Valid expressions

In addition to the expressions defined in Sorted Associative Container and Multiple Associative Container, the following expressions must be valid.
Name | Expression | Type requirements | Return type
Range constructor
X(i, j)
X a(i, j);
i and j are Input Iterators whose value type is convertible to T [1]. X
Range constructor with compare

X(i, j, c)
X a(i, j, c);
i and j are Input Iterators whose value type is convertible to T [1]. c is an object of type key_compare. X
Insert with hint | a.insert(p, t) | iterator
Insert range | a.insert(i, j) | i and j are Input Iterators whose value type is convertible to X::value_type. [1] | void

Expression semantics

Name | Expression | Precondition | Semantics | Postcondition
Range constructor
X(i, j)
X a(i, j);
[i,j) is a valid range. Creates an associative container that contains all of the elements in the range [i,j). The comparison object used by the container is key_compare(). size() is equal to the distance from i to j.
Range constructor with compare

X(i, j, c)
X a(i, j, c);
[i,j) is a valid range. Creates an associative container that contains all of the elements in the range [i,j). The comparison object used by the container is c. size() is equal to the distance from i to j.
Insert with hint | a.insert(p, t) | p is a nonsingular iterator in a. | Inserts t into a. The argument p is a hint: it points to the location where the search will begin. The return value is a dereferenceable iterator that points to the element that was just inserted. | a contains an element whose key is the same as that of t. The size of a is incremented by 1.
Insert range | a.insert(i, j) | [i, j) is a valid range. | Equivalent to a.insert(t) for each object t that is pointed to by an iterator in the range [i, j). Each element is inserted into a. | The size of a is incremented by j - i.

Complexity guarantees

The range constructor, and range constructor with compare, are in general O(N * log(N)), where N is the size of the range. However, they are linear in N if the range is already sorted by value_comp().

Insert with hint is logarithmic in general, but it is amortized constant time if t is inserted immediately before p.

Insert range is in general O(N * log(N)), where N is the size of the range. However, it is linear in N if the range is already sorted by value_comp().

Invariants

Models

  • multimap
  • multiset

Notes

[1] At present (early 1998), not all compilers support "member templates". If your compiler supports member templates then i and j may be of any type that conforms to the Input Iterator requirements. If your compiler does not yet support member templates, however, then i and j must be of type const T* or of type X::const_iterator.

See also

Associative Container, Sorted Associative Container, Unique Sorted Associative Container Hashed Associative Container


multiset<Key, Compare, Alloc>

Category: containers | Component type: type

Description

Multiset is a Sorted Associative Container that stores objects of type Key. Multiset is a Simple Associative Container, meaning that its value type, as well as its key type, is Key. It is also a Multiple Associative Container, meaning that two or more elements may be identical.

Set and multiset are particularly well suited to the set algorithms includes, set_union, set_intersection, set_difference, and set_symmetric_difference. The reason for this is twofold. First, the set algorithms require their arguments to be sorted ranges, and, since set and multiset are Sorted Associative Containers, their elements are always sorted in ascending order. Second, the output range of these algorithms is always sorted, and inserting a sorted range into a set or multiset is a fast operation: the Unique Sorted Associative Container and Multiple Sorted Associative Container requirements guarantee that inserting a range takes only linear time if the range is already sorted.

Multiset has the important property that inserting a new element into a multiset does not invalidate iterators that point to existing elements. Erasing an element from a multiset also does not invalidate any iterators, except, of course, for iterators that actually point to the element that is being erased.

Example

int main()
{
  const int N = 10;
  int a[N] = {4, 1, 1, 1, 1, 1, 0, 5, 1, 0};
  int b[N] = {4, 4, 2, 4, 2, 4, 0, 1, 5, 5};

  multiset<int> A(a, a + N);
  multiset<int> B(b, b + N);
  multiset<int> C;

  cout << "Set A: ";
  copy(A.begin(), A.end(), ostream_iterator<int>(cout, " "));
  cout << endl;
  cout << "Set B: ";
  copy(B.begin(), B.end(), ostream_iterator<int>(cout, " "));
  cout << endl;

  cout << "Union: ";
  set_union(A.begin(), A.end(), B.begin(), B.end(),
            ostream_iterator<int>(cout, " "));
  cout << endl;

  cout << "Intersection: ";
  set_intersection(A.begin(), A.end(), B.begin(), B.end(),
                   ostream_iterator<int>(cout, " "));
  cout << endl;

  set_difference(A.begin(), A.end(), B.begin(), B.end(),
                 inserter(C, C.begin()));
  cout << "Set C (difference of A and B): ";
  copy(C.begin(), C.end(), ostream_iterator<int>(cout, " "));
  cout << endl;
}

Definition

Defined in the standard header set, and in the nonstandard backward-compatibility header multiset.h.

Template parameters

Parameter | Description | Default
Key | The set's key type and value type. This is also defined as multiset::key_type and multiset::value_type |
Compare | The key comparison function, a Strict Weak Ordering whose argument type is key_type; it returns true if its first argument is less than its second argument, and false otherwise. This is also defined as multiset::key_compare and multiset::value_compare. | less<Key>
Alloc | The multiset's allocator, used for all internal memory management. | alloc

Model of

Multiple Sorted Associative Container, Simple Associative Container

Type requirements

  • Key is Assignable.
  • Compare is a Strict Weak Ordering whose argument type is Key.
  • Alloc is an Allocator.

Public base classes

None.

Members

Member | Where defined | Description
value_type | Container | The type of object, T, stored in the multiset.
key_type | Associative Container | The key type associated with value_type.
key_compare | Sorted Associative Container | Function object that compares two keys for ordering.
value_compare | Sorted Associative Container | Function object that compares two values for ordering.
pointer | Container | Pointer to T.
reference | Container | Reference to T
const_reference | Container | Const reference to T
size_type | Container | An unsigned integral type.
difference_type | Container | A signed integral type.
iterator | Container | Iterator used to iterate through a multiset.
const_iterator | Container | Const iterator used to iterate through a multiset. (Iterator and const_iterator are the same type.)
reverse_iterator | Reversible Container | Iterator used to iterate backwards through a multiset.
const_reverse_iterator | Reversible Container | Const iterator used to iterate backwards through a multiset. (Reverse_iterator and const_reverse_iterator are the same type.)
iterator begin() const | Container | Returns an iterator pointing to the beginning of the multiset.
iterator end() const | Container | Returns an iterator pointing to the end of the multiset.
reverse_iterator rbegin() const | Reversible Container | Returns a reverse_iterator pointing to the beginning of the reversed multiset.
reverse_iterator rend() const | Reversible Container | Returns a reverse_iterator pointing to the end of the reversed multiset.
size_type size() const | Container | Returns the size of the multiset.
size_type max_size() const | Container | Returns the largest possible size of the multiset.
bool empty() const | Container | true if the multiset's size is 0.
key_compare key_comp() const | Sorted Associative Container | Returns the key_compare object used by the multiset.
value_compare value_comp() const | Sorted Associative Container | Returns the value_compare object used by the multiset.
multiset() | Container | Creates an empty multiset.
multiset(const key_compare& comp) | Sorted Associative Container | Creates an empty multiset, using comp as the key_compare object.
template <class InputIterator>
multiset(InputIterator f, InputIterator l)
[1]
Multiple Sorted Associative Container Creates a multiset with a copy of a range.
template <class InputIterator>
multiset(InputIterator f, InputIterator l,
         const key_compare& comp)
[1]
Multiple Sorted Associative Container Creates a multiset with a copy of a range, using comp as the key_compare object.
multiset(const multiset&) | Container | The copy constructor.
multiset& operator=(const multiset&) | Container | The assignment operator
void swap(multiset&) | Container | Swaps the contents of two multisets.
iterator insert(const value_type& x) | Multiple Associative Container | Inserts x into the multiset.
iterator insert(iterator pos,
                const value_type& x)
Multiple Sorted Associative Container Inserts x into the multiset, using pos as a hint to where it will be inserted.
template <class InputIterator>
void insert(InputIterator, InputIterator)
[1]
Multiple Sorted Associative Container Inserts a range into the multiset.
void erase(iterator pos) | Associative Container | Erases the element pointed to by pos.
size_type erase(const key_type& k) | Associative Container | Erases the element whose key is k.
void erase(iterator first, iterator last) | Associative Container | Erases all elements in a range.
void clear() | Associative Container | Erases all of the elements.
iterator find(const key_type& k) const | Associative Container | Finds an element whose key is k.
size_type count(const key_type& k) const | Associative Container | Counts the number of elements whose key is k.
iterator lower_bound(const key_type& k) const | Sorted Associative Container | Finds the first element whose key is not less than k.
iterator upper_bound(const key_type& k) const | Sorted Associative Container | Finds the first element whose key greater than k.
pair<iterator, iterator>
equal_range(const key_type& k) const
Sorted Associative Container Finds a range containing all elements whose key is k.
bool operator==(const multiset&,
                const multiset&)
Forward Container Tests two multisets for equality. This is a global function, not a member function.
bool operator<(const multiset&,
               const multiset&)
Forward Container Lexicographical comparison. This is a global function, not a member function.

New members

All of multiset's members are defined in the Multiple Sorted Associative Container and Simple Associative Container requirements. Multiset does not introduce any new members.

Notes

[1] This member function relies on member template functions, which at present (early 1998) are not supported by all compilers. If your compiler supports member templates, you can call this function with any type of input iterator. If your compiler does not yet support member templates, though, then the arguments must either be of type const value_type* or of type multiset::const_iterator.

See also

Associative Container, Sorted Associative Container, Simple Associative Container, Multiple Sorted Associative Container, set, map, multimap, hash_set, hash_map, hash_multiset, hash_multimap


negate<T>

Category: functors | Component type: type

Description

Negate<T> is a function object. Specifically, it is an Adaptable Unary Function. If f is an object of class negate<T> and x is an object of class T, then f(x) returns -x.

Example

Each element in V2 will be the negative (additive inverse) of the corresponding element in V1.
const int N = 1000;
vector<double> V1(N);
vector<double> V2(N);

iota(V1.begin(), V1.end(), 1);

assert(V2.size() >= V1.size());
transform(V1.begin(), V1.end(), V2.begin(),
          negate<int>());

Definition

Defined in the standard header functional, and in the nonstandard backward-compatibility header function.h.

Template parameters

Parameter | Description | Default
T | The function object's argument type and result type. |

Model of

Adaptable Unary Function, Default Constructible

Type requirements

T must be a numeric type; if x is an object of type T, then -x must be defined and must have a return type that is convertible to T. T must be Assignable.

Public base classes

unary_function<T, T>

Members

Member | Where defined | Description
argument_type | Adaptable Unary Function | The type of the second argument: T
result_type | Adaptable Unary Function | The type of the result: T
T operator()(const T& x) | Adaptable Unary Function | Function call operator. The return value is -x.
negate() | Default Constructible | The default constructor.

New members

All of negate's members are defined in the Adaptable Unary Function and Default Constructible requirements. Negate does not introduce any new members.

Notes

See also

The Function Object overview, Adaptable Unary Function, unary_function, plus, minus, multiplies, divides, modulus


next_permutation

Category: algorithms | Component type: function

Prototype

Next_permutation is an overloaded name; there are actually two next_permutation functions.
template <class BidirectionalIterator>
bool next_permutation(BidirectionalIterator first,
                      BidirectionalIterator last);

template <class BidirectionalIterator, class StrictWeakOrdering>
bool next_permutation(BidirectionalIterator first, BidirectionalIterator last,
                      StrictWeakOrdering comp);

Description

Next_permutation transforms the range of elements [first, last) into the lexicographically next greater permutation of the elements. There is a finite number of distinct permutations (at most N! [1], where N is last - first), so, if the permutations are ordered by lexicographical_compare, there is an unambiguous definition of which permutation is lexicographically next. If such a permutation exists, next_permutation transforms [first, last) into that permutation and returns true. Otherwise it transforms [first, last) into the lexicographically smallest permutation [2] and returns false.

The postcondition is that the new permutation of elements is lexicographically greater than the old (as determined by lexicographical_compare) if and only if the return value is true.

The two versions of next_permutation differ in how they define whether one element is less than another. The first version compares objects using operator<, and the second compares objects using a function object comp.

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

For the first version, the one that takes two arguments:
  • BidirectionalIterator is a model of Bidirectional Iterator.
  • BidirectionalIterator is mutable.
  • BidirectionalIterator's value type is LessThan Comparable.
  • The ordering relation on BidirectionalIterator's value type is a strict weak ordering, as defined in the LessThan Comparable requirements.
For the second version, the one that takes three arguments:
  • BidirectionalIterator is a model of Bidirectional Iterator.
  • BidirectionalIterator is mutable.
  • StrictWeakOrdering is a model of Strict Weak Ordering.
  • BidirectionalIterator's value type is convertible to StrictWeakOrdering's argument type.

Preconditions

  • [first, last) is a valid range.

Complexity

Linear. At most (last - first) / 2 swaps.

Example

This example uses next_permutation to implement the worst known deterministic sorting algorithm. Most sorting algorithms are O(N log(N)), and even bubble sort is only O(N^2). This algorithm is actually O(N!).
template <class BidirectionalIterator>
void snail_sort(BidirectionalIterator first, BidirectionalIterator last)
{
  while (next_permutation(first, last)) {}
}

int main()
{
  int A[] = {8, 3, 6, 1, 2, 5, 7, 4};
  const int N = sizeof(A) / sizeof(int);

  snail_sort(A, A+N);
  copy(A, A+N, ostream_iterator<int>(cout, "\n"));
}

Notes

[1] If all of the elements in [first, last) are distinct from each other, then there are exactly N! permutations. If some elements are the same as each other, though, then there are fewer. There are, for example, only three (3!/2!) permutations of the elements 1 1 2.

[2] Note that the lexicographically smallest permutation is, by definition, sorted in nondecreasing order.

See also

prev_permutation, lexicographical_compare, LessThan Comparable, Strict Weak Ordering, sort


not_equal_to<T>

Category: functors | Component type: type

Description

Not_equal_to<T> is a function object. Specifically, it is an Adaptable Binary Predicate, which means it is a function object that tests the truth or falsehood of some condition. If f is an object of class not_equal_to<T> and x and y are objects of class T, then f(x,y) returns true if x != y and false otherwise.

Example

Finds the first nonzero element in a list.
list<int> L;
...
list<int>::iterator first_nonzero =
       find_if(L.begin(), L.end(), bind2nd(not_equal_to<int>(), 0));
assert(first_nonzero == L.end() || *first_nonzero != 0);

Definition

Defined in the standard header functional, and in the nonstandard backward-compatibility header function.h.

Template parameters

Parameter | Description | Default
T | The type of not_equal_to's arguments. |

Model of

Adaptable Binary Predicate, DefaultConstructible

Type requirements

T is EqualityComparable.

Public base classes

binary_function<T, T, bool>.

Members

Member | Where defined | Description
first_argument_type | Adaptable Binary Predicate | The type of the first argument: T
second_argument_type | Adaptable Binary Predicate | The type of the second argument: T
result_type | Adaptable Binary Predicate | The type of the result: bool
not_equal_to() | DefaultConstructible | The default constructor.
bool operator()(const T& x, const T& y) | Binary Function | Function call operator. The return value is x != y.

New members

All of not_equal_to's members are defined in the Adaptable Binary Predicate and DefaultConstructible requirements. Not_equal_to does not introduce any new members.

Notes

See also

The function object overview, Adaptable Binary Predicate, equal_to, greater, less, greater_equal, less_equal


nth_element

Category: algorithms | Component type: function

Prototype

Nth_element is an overloaded name; there are actually two nth_element functions.
template <class RandomAccessIterator>
void nth_element(RandomAccessIterator first, RandomAccessIterator nth,
                 RandomAccessIterator last);

template <class RandomAccessIterator, class StrictWeakOrdering>
void nth_element(RandomAccessIterator first, RandomAccessIterator nth,
                 RandomAccessIterator last, StrictWeakOrdering comp);

Description

Nth_element is similar to partial_sort, in that it partially orders a range of elements: it arranges the range [first, last) such that the element pointed to by the iterator nth is the same as the element that would be in that position if the entire range [first, last) had been sorted. Additionally, none of the elements in the range [nth, last) is less than any of the elements in the range [first, nth). [1]

The two versions of nth_element differ in how they define whether one element is less than another. The first version compares objects using operator<, and the second compares objects using a function object comp.

The postcondition for the first version of nth_element is as follows. There exists no iterator i in the range [first, nth) such that *nth < *i, and there exists no iterator j in the range [nth + 1, last) such that *j < *nth.

The postcondition for the second version of nth_element is as follows. There exists no iterator i in the range [first, nth) such that comp(*nth, *i) is true, and there exists no iterator j in the range [nth + 1, last) such that comp(*j, *nth) is true.

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

For the first version, the one that takes three arguments:
  • RandomAccessIterator is a model of Random Access Iterator.
  • RandomAccessIterator is mutable.
  • RandomAccessIterator's value type is LessThan Comparable.
  • The ordering relation on RandomAccessIterator's value type is a strict weak ordering, as defined in the LessThan Comparable requirements.
For the second version, the one that takes four arguments:
  • RandomAccessIterator is a model of Random Access Iterator.
  • RandomAccessIterator is mutable.
  • StrictWeakOrdering is a model of Strict Weak Ordering.
  • RandomAccessIterator's value type is convertible to StrictWeakOrdering's argument type.

Preconditions

  • [first, nth) is a valid range.
  • [nth, last) is a valid range.
(It follows from these two conditions that [first, last) is a valid range.)

Complexity

On average, linear in last - first. [2]

Example

int A[] = {7, 2, 6, 11, 9, 3, 12, 10, 8, 4, 1, 5};
const int N = sizeof(A) / sizeof(int);

nth_element(A, A + 6, A + N);
copy(A, A + N, ostream_iterator<int>(cout, " "));
// The printed result is "5 2 6 1 4 3 7 8 9 10 11 12".

Notes

[1] The way in which this differs from partial_sort is that neither the range [first, nth) nor the range [nth, last) is be sorted: it is simply guaranteed that none of the elements in [nth, last) is less than any of the elements in [first, nth). In that sense, nth_element is more similar to partition than to sort. Nth_element does less work than partial_sort, so, reasonably enough, it is faster. That's the main reason to use nth_element instead of partial_sort.

[2] Note that this is significantly less than the run-time complexity of partial_sort.

See also

partial_sort, partition, sort, StrictWeakOrdering, LessThan Comparable


Relational Operators

Category: utilities | Component type: function

Prototype

template <class T> bool operator!=(const T& x, const T& y);
template <class T> bool operator>(const T& x, const T& y);
template <class T> bool operator<=(const T& x, const T& y);
template <class T> bool operator>=(const T& x, const T& y);

Description

The Equality Comparable requirements specify that it must be possible to compare objects using operator!= as well as operator==; similarly, the LessThan Comparable requirements include operator>, operator<= and operator>= as well as operator<. Logically, however, most of these operators are redundant: all of them can be defined in terms of operator== and operator<.

These four templates use operator== and operator< to define the other four relational operators. They exist purely for the sake of convenience: they make it possible to write algorithms in terms of the operators !=, >, <=, and >=, without requiring that those operators be explicitly defined for every type.

As specified in the Equality Comparable requirements, x != y is equivalent to !(x == y). As specified in the LessThan Comparable requirements, x > y is equivalent to y < x, x >= y is equivalent to !(x < y), and x <= y is equivalent to !(y < x).

Definition

Defined in the standard header utility, and in the nonstandard backward-compatibility header function.h.

Requirements on types

The requirement for operator!= is that x == y is a valid expression for objects x and y of type T.

The requirement for operator> is that y < x is a valid expression for objects x and y of type T.

The requirement for operator<= is that y < x is a valid expression for objects x and y of type T.

The requirement for operator>= is that x < y is a valid expression for objects x and y of type T.

Preconditions

The precondition for operator!= is that x and y are in the domain of operator==.

The precondition for operator>, operator<=, and operator>= is that x and y are in the domain of operator<.

Complexity

Example

template <class T> void relations(T x, T y)
{
  if (x == y) assert(!(x != y));
  else assert(x != y);

  if (x < y) {
    assert(x <= y);
    assert(y > x);
    assert(y >= x);
  }
  else if (y < x) {
    assert(y <= x);
    assert(x < y);
    assert(x <= y);
  }
  else {
    assert(x <= y);
    assert(x >= y);
  }
}

Notes

See also

Equality Comparable, LessThan Comparable


ostream_iterator<T>

Category: iterators | Component type: type

Description

An ostream_iterator is an Output Iterator that performs formatted output of objects of type T to a particular ostream. Note that all of the restrictions of an Output Iterator must be obeyed, including the restrictions on the ordering of operator* and operator++ operations.

Example

Copy the elements of a vector to the standard output, one per line.
vector<int> V;
// ...
copy(V.begin(), V.end(), ostream_iterator<int>(cout, "\n"));

Definition

Defined in the standard header iterator, and in the nonstandard backward-compatibility header iterator.h.

Template parameters

Parameter | Description | Default
T | The type of object that will be written to the ostream. The set of value types of an ostream_iterator consists of a single type, T. |

Model of

Output Iterator.

Type requirements

T must be a type such that cout << T is a valid expression.

Public base classes

None.

Members

Member | Where defined | Description
ostream_iterator(ostream&) | ostream_iterator | See below.
ostream_iterator(ostream&, const char* s) | ostream_iterator | See below.
ostream_iterator(const ostream_iterator&) | Output Iterator | The copy constructor
ostream_iterator& operator=(const ostream_iterator&) | Output Iterator | The assignment operator
ostream_iterator& operator=(const T&) | Output Iterator | Used to implement the Output Iterator requirement *i = t. [1]
ostream_iterator& operator*() | Output Iterator | Used to implement the Output Iterator requirement *i = t. [1]
ostream_iterator& operator++() | Output Iterator | Preincrement
ostream_iterator& operator++(int) | Output Iterator | Postincrement
output_iterator_tag iterator_category(const ostream_iterator&) | iterator tags | Returns the iterator's category.

New members

These members are not defined in the Output Iterator requirements, but are specific to ostream_iterator.
Function | Description
ostream_iterator(ostream& s) | Creates an ostream_iterator such that assignment of t through it is equivalent to s << t.
ostream_iterator(ostream& s, const char* delim) | Creates an ostream_iterator such that assignment of t through it is equivalent to s << t << delim.

Notes

[1] Note how assignment through an ostream_iterator is implemented. In general, unary operator* must be defined so that it returns a proxy object, where the proxy object defines operator= to perform the output operation. In this case, for the sake of simplicity, the proxy object is the ostream_iterator itself. That is, *i simply returns i, and *i = t is equivalent to i = t. You should not, however, rely on this behavior. It is an implementation detail, and it is not guaranteed to remain the same in future versions.

See also

istream_iterator, Output Iterator, Input Iterator.


Other STL resources

 SGI

Other STL Web sites

  • The Matrix Template Library at Notre Dame. A high-performance generic linear algebra library.
  • The Rensselaer STL site by David Musser
  • The Renssalaer STL online reference
  • The STL tutorial at Technical University Vienna
  • Port of the SGI STL to other compilers, by Boris Fomitchev.
  • Port of the SGI STL to Microsoft Windows CE compilers, by Giuseppe Govi.
  • The STL Newbie Guide by Mumit Khan
  • A Tiny STL Primer by David Harvey
  • A Very Modest STL Tutorial by Jak Kirman
  • The Dinkum Standard Template Library Reference by P. J. Plauger.
  • Overview of the STL by G. Bowden Wise
  • Ian Burrell's STL page
  • Cay Horstmann's "Safe STL"
  • The Binder Library. A versatile function argument binding mechanism that interoperates with STL algorithms.
  • The STL Resource List by Warren Young
  • The Standard Template Library Overview by Rob Kremer
  • Alexander Stepanov's Byte Magazine's article
  • Dr. Dobb's Journal interview with Alexander Stepanov

Books about the STL and generic programming

STL for C++ Programmers, by Leen Ammeraal. John Wiley, 1996. ISBN 0-471-97181-2.

Generic Programming and the STL, by Matthew Austern. Addison-Wesley, 1998. ISBN 0-201-30956-4.

Designing Components with the C++ STL, by Ulrich Breymann. Addison Wesley Longman, 1998. ISBN 0-201-17816-8.

Data Structures in C++ Using the Standard Template Library, by Timothy Budd. Addison-Wesley, 1997.

The STL Primer, by Graham Glass and Brett Schuchert. Prentice-Hall, 1996. ISBN 0134549767

The C++ Standard Library - A Tutorial and Reference, by Nicolai Josuttis. Addison Wesley Longman, 1999. ISBN 0-201-37926-0. (English translation of Die C++-Standardbibliothek.)

STL Tutorial and Reference Guide, by David Musser and Atul Saini. Addison-Wesley, 1996. ISBN 0-201-63398-1.

C++ Programmer's Guide to the Standard Template Library, by Mark Nelson. IDG Books, 1995. ISBN 1-56884-314-3. (No longer in print.)

The Standard Template Library, by P. J. Plauger, Alexander Stepanov, Meng Lee, and David Musser. Prentice-Hall. ISBN 0-13-437633-1. (forthcoming)

Using the STL, by Robert Robson. Springer-Verlag, 1998.

STL Programming from the Ground Up, by Herbert Schildt. Osborne McGraw-Hill, 1999.

We welcome additions to this list. Please send suggestions to stl@sgi.com.


Output Iterator

Category: iterators | Component type: concept

Description

An Output Iterator is a type that provides a mechanism for storing (but not necessarily accessing) a sequence of values. Output Iterators are in some sense the converse of Input Iterators, but they have a far more restrictive interface: they do not necessarily support member access or equality, and they do not necessarily have either an associated distance type or even a value type [1]. Intuitively, one picture of an Output Iterator is a tape: you can write a value to the current location and you can advance to the next location, but you cannot read values and you cannot back up or rewind.

Refinement of

Assignable, DefaultConstructible

Associated types

None. [1]

Notation

X | A type that is a model of Output Iterator
x, y | Object of type X

Definitions

If x is an Output Iterator of type X, then the expression *x = t; stores the value t into x. Note that operator=, like other C++ functions, may be overloaded; it may, in fact, even be a template function. In general, then, t may be any of several different types. A type T belongs to the set of value types of X if, for an object t of type T, *x = t; is well-defined and does not require performing any non-trivial conversions on t. [1]

An Output Iterator may be singular, meaning that the results of most operations, including copying and dereference assignment, are undefined. The only operation that is guaranteed to be supported is assigning a nonsingular iterator to a singular iterator.

An Output Iterator may be dereferenceable, meaning that assignment through it is defined. Dereferenceable iterators are always nonsingular, but nonsingular iterators are not necessarily dereferenceable.

Valid expressions

Name | Expression | Type requirements | Return type
Default constructor
X x;
X()
Copy constructor | X(x) | X
Copy constructor | X y(x); or X y = x;
Dereference assignment | *x = t | t is convertible to a type in the set of value types of X. [1] | Result is not used
Preincrement | ++x | X&
Postincrement | (void) x++ | void
Postincrement and assign | *x++ = t; | Result is not used

Expression semantics

Name | Expression | Precondition | Semantics | Postcondition
Default constructor
X x;
X()
x may be singular
Copy constructor | X(x) | x is nonsingular | *X(x) = t is equivalent to *x = t [2]
Copy constructor | X x(y); or X x = y; | y is nonsingular | *y = t is equivalent to *x = t [2]
Dereference assignment | *x = t | x is dereferenceable. If there has been a previous assignment through x, then there has been an intervening increment. [3]
Preincrement | ++x | x is dereferenceable. x has previously been assigned through. If x has previously been incremented, then there has been an intervening assignment through x [3] [4] | x points to the next location into which a value may be stored
Postincrement | (void) x++ | x is dereferenceable. x has previously been assigned through. | Equivalent to (void) ++x | x points to the next location into which a value may be stored
Postincrement and assign | *x++ = t; | x is dereferenceable. If there has been a previous assignment through x, then there has been an intervening increment. [3] [4] | Equivalent to {*x = t; ++x; } | x points to the next location into which a value may be stored

Complexity guarantees

The complexity of operations on output iterators is guaranteed to be amortized constant time.

Invariants

Models

  • ostream_iterator
  • insert_iterator
  • front_insert_iterator
  • back_insert_iterator

Notes

[1] Other iterator types, including Trivial Iterator and Input Iterator, define the notion of a value type, the type returned when an iterator is dereferenced. This notion does not apply to Output Iterators, however, since the dereference operator (unary operator*) does not return a usable value for Output Iterators. The only context in which the dereference operator may be used is assignment through an output iterator: *x = t. Although Input Iterators and output iterators are roughly symmetrical concepts, there is an important sense in which accessing and storing values are not symmetrical: for an Input Iterator operator* must return a unique type, but, for an Output Iterator, in the expression *x = t, there is no reason why operator= must take a unique type. [5] Consequently, there need not be any unique "value type" for Output Iterators.

[2] There should be only one active copy of a single Output Iterator at any one time. That is: after creating and using a copy x of an Output Iterator y, the original output iterator y should no longer be used.

[3] Assignment through an Output Iterator x is expected to alternate with incrementing x, and there must be an assignment through x before x is ever incremented. Any other order of operations results in undefined behavior. That is: {*x = t; ++x; *x = t2; ++x} is acceptable, but {*x = t; ++x; ++x; *x = t2;} is not.

[4] Note that an Output Iterator need not define comparison for equality. Even if an operator== is defined, x == y need not imply ++x == ++y.

[5] If you are implementing an Output Iterator class X, one sensible way to define *x = t is to define X::operator*() to return an object of some private class X_proxy, and then to define X_proxy::operator=. Note that you may overload X_proxy::operator=, or even define it as a member template; this allows assignment of more than one type through Output Iterators of class X.

See also

Trivial Iterator, Input Iterator, Iterator overview


output_iterator

Category: iterators | Component type: type

Description

Output_iterator is an iterator base class: it is intended that an iterator that is a model of Output Iterator may be defined by inheriting from output_iterator [1]. Output_iterator is entirely empty: it has no member functions, member variables, or nested types. It exists solely to simplify the definition of the functions iterator_category, distance_type, and value_type.

Example

class my_output_iterator : public output_iterator
{
  ...
};
This declares my_output_iterator to be an Output Iterator. If Iter is an object of class my_output_iterator, then iterator_category(Iter) will return output_iterator_tag(), and distance_type and value_type will be undefined for objects of class my_output_iterator.

Definition

Defined in the standard header iterator, and in the nonstandard backward-compatibility header iterator.h. This class is no longer part of the C++ standard, although it was present in early drafts of the standard. It is retained in this implementation for backward compatibility.

Template parameters

None. (Note that Output Iterators need have neither distance types nor value types.)

Model of

Assignable

Public base classes

None

Type requirements

None.

Public base classes

None.

Members

None.

New Members

None.

Notes

[1] It is not required that an Output Iterator inherit from the base output_iterator. It is, however, required that the function iterator_category be defined for every Output Iterator. (Or, if you are using the iterator_traits mechanism, that iterator_traits is properly specialized for every Output Iterator.) Since it is defined for the base output_iterator, the easiest way to ensure that it defined for a new type is to derive that class from output_iterator and rely on the derived-to-base standard conversion of function arguments.

See also

The Iterator Tags overview, iterator_traits, iterator_category, value_type, distance_type, input_iterator, forward_iterator, bidirectional_iterator, random_access_iterator


output_iterator_tag

Category: iterators | Component type: type

Description

Output_iterator_tag is an empty class: it has no member functions, member variables, or nested types. It is used solely as a "tag": a representation of the Output Iterator concept within the C++ type system. Specifically, it is used as a return value for the function iterator_category. Iterator_category takes a single argument, an iterator, and returns an object whose type depends on the iterator's category. Iterator_category's return value is of type output_iterator_tag if its argument is an Output Iterator.

Example

See iterator_category

Definition

Defined in the standard header iterator, and in the nonstandard backward-compatibility header iterator.h.

Template parameters

None.

Model of

Assignable

Type requirements

None.

Public base classes

None.

Members

None.

New Members

None.

Notes

See also

iterator_category, Iterator Tags, iterator_traits, input_iterator_tag, forward_iterator_tag, bidirectional_iterator_tag, random_access_iterator_tag


pair<T1, T2>

Category: utilities | Component type: type

Description

Pair<T1,T2> is a heterogeneous pair: it holds one object of type T1 and one of type T2. A pair is much like a Container, in that it "owns" its elements. It is not actually a model of Container, though, because it does not support the standard methods (such as iterators) for accessing the elements of a Container.

Functions that need to return two values often return a pair.

Example

pair<bool, double> result = do_a_calculation();
if (result.first)
  do_something_more(result.second);
else
  report_error();

Definition

Defined in the standard header utility, and in the nonstandard backward-compatibility header pair.h.

Template parameters

Parameter | Description | Default
T1 | The type of the first element stored in the pair |
T2 | The type of the second element stored in the pair |

Model of

Assignable

Type requirements

T1 and T2 must both be models of Assignable. Additional operations have additional requirements. Pair's default constructor may only be used if both T1 and T2 are DefaultConstructible, operator== may only be used if both T1 and T2 are EqualityComparable, and operator< may only be used if both T1 and T2 are LessThanComparable.

Public base classes

None.

Members

Member | Where defined | Description
first_type | pair | See below.
second_type | pair | See below.
pair() | pair | The default constructor. See below.
pair(const first_type&, const second_type&) | pair | The pair constructor. See below.
pair(const pair&) | Assignable | The copy constructor
pair& operator=(const pair&) | Assignable | The assignment operator
first | pair | See below.
second | pair | See below.
bool operator==(const pair&, const pair&) | pair | See below.
bool operator<(const pair&, const pair&) | pair | See below.
template <class T1, class T2>
pair<T1, T2> make_pair(const T1&, const T2&)
pair See below.

New members

These members are not defined in the Assignable requirements, but are specific to pair.
Member | Description
first_type | The type of the pair's first component. This is a typedef for the template parameter T1
second_type | The type of the pair's second component. This is a typedef for the template parameter T2
pair() | The default constructor. It uses constructs objects of types T1 and T2 using their default constructors. This constructor may only be used if both T1 and T2 are DefaultConstructible.
pair(const first_type& x, const second_type& y) | The pair constructor. Constructs a pair such that first is constructed from x and second is constructed from y.
first | Public member variable of type first_type: the first object stored in the pair.
second | Public member variable of type second_type: The second object stored in the pair.
template <class T1, class T2>
bool operator==(const pair<T1,T2>& x,
                const pair<T1,T2>& y);
The equality operator. The return value is true if and only the first elements of x and y are equal, and the second elements of x and y are equal. This operator may only be used if both T1 and T2 are EqualityComparable. This is a global function, not a member function.
template <class T1, class T2>
bool operator<(const pair<T1,T2>& x,
               const pair<T1,T2>& y);
The comparison operator. It uses lexicographic comparison: the return value is true if the first element of x is less than the first element of y, and false if the first element of y is less than the first element of x. If neither of these is the case, then operator< returns the result of comparing the second elements of x and y. This operator may only be used if both T1 and T2 are LessThanComparable. This is a global function, not a member function.
template <class T1, class T2>
pair<T1, T2> make_pair(const T1& x, const T2& x)
Equivalent to pair<T1, T2>(x, y). This is a global function, not a member function. It exists only for the sake of convenience.

Notes

See also

Assignable, Default Constructible, LessThan Comparable


Pair Associative Container

Category: containers | Component type: concept

Description

A Pair Associative Container is an Associative Container that associates a key with some other object. The value type of a Pair Associative Container is pair<const key_type, data_type>. [1]

Refinement of

Associative Container

Associated types

One new type is introduced, in addition to the types defined in the Associative Container requirements. Additionally, Pair Associative Container introduces one new type restriction
Key type | X::key_type | The type of the key associated with X::value_type.
Data type | X::data_type | The type of the data associated with X::value_type. A Pair Associative Container can be thought of as a mapping from key_type to data_type.
Value type | X::value_type | The type of object stored in the container. The value type is required to be pair<const key_type, data_type>.

Notation

X | A type that is a model of Pair Associative Container
a | Object of type X
t | Object of type X::value_type
d | Object of type X::data_type
k | Object of type X::key_type
p, q | Object of type X::iterator

Definitions

Valid expressions

None, except for those defined in the Associative Container requirements.

Expression semantics

Complexity guarantees

Invariants

Models

  • map
  • multimap
  • hash_map
  • hash_multimap

Notes

[1] The value type must be pair<const key_type, data_type>, rather than pair<key_type, data_type>, because of the Associative Container invariant of key immutability. The data_type part of an object in a Pair Associative Container may be modified, but the key_type part may not be. Note the implication of this fact: a Pair Associative Container cannot provide mutable iterators (as defined in the Trivial Iterator requirements), because the value type of a mutable iterator must be Assignable, and pair<const key_type, data_type> is not Assignable. However, a Pair Associative Container can provide iterators that are not completely constant: iterators such that the expression (*i).second = d is valid.

See also

Associative Container, Simple Associative Container


partial_sort

Category: algorithms | Component type: function

Prototype

Partial_sort is an overloaded name; there are actually two partial_sort functions.
template <class RandomAccessIterator>
void partial_sort(RandomAccessIterator first,
                  RandomAccessIterator middle,
                  RandomAccessIterator last);

template <class RandomAccessIterator, class StrictWeakOrdering>
void partial_sort(RandomAccessIterator first,
                  RandomAccessIterator middle,
                  RandomAccessIterator last,
                  StrictWeakOrdering comp);

Description

Partial_sort rearranges the elements in the range [first, last) so that they are partially in ascending order. Specifically, it places the smallest middle - first elements, sorted in ascending order, into the range [first, middle). The remaining last - middle elements are placed, in an unspecified order, into the range [middle, last). [1] [2]

The two versions of partial_sort differ in how they define whether one element is less than another. The first version compares objects using operator<, and the second compares objects using a function object comp.

The postcondition for the first version of partial_sort is as follows. If i and j are any two valid iterators in the range [first, middle) such that i precedes j, and if k is a valid iterator in the range [middle, last), then *j < *i and *k < *i will both be false. The corresponding postcondition for the second version of partial_sort is that comp(*j, *i) and comp(*k, *i) are both false. Informally, this postcondition means that the first middle - first elements are in ascending order and that none of the elements in [middle, last) is less than any of the elements in [first, middle).

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

For the first version:
  • RandomAccessIterator is a model of Random Access Iterator.
  • RandomAccessIterator is mutable.
  • RandomAccessIterator's value type is LessThan Comparable.
  • The ordering relation on RandomAccessIterator's value type is a strict weak ordering, as defined in the LessThan Comparable requirements.
For the second version:
  • RandomAccessIterator is a model of Random Access Iterator.
  • RandomAccessIterator is mutable.
  • StrictWeakOrdering is a model of Strict Weak Ordering.
  • RandomAccessIterator's value type is convertible to StrictWeakOrdering's argument type.

Preconditions

  • [first, middle) is a valid range.
  • [middle, last) is a valid range.
(It follows from these two conditions that [first, last) is a valid range.)

Complexity

Approximately (last - first) * log(middle - first) comparisons.

Example

int A[] = {7, 2, 6, 11, 9, 3, 12, 10, 8, 4, 1, 5};
const int N = sizeof(A) / sizeof(int);

partial_sort(A, A + 5, A + N);
copy(A, A + N, ostream_iterator<int>(cout, " "));
// The printed result is "1 2 3 4 5 11 12 10 9 8 7 6".

Notes

[1] Note that the elements in the range [first, middle) will be the same (ignoring, for the moment, equivalent elements) as if you had sorted the entire range using sort(first, last). The reason for using partial_sort in preference to sort is simply efficiency: a partial sort, in general, takes less time.

[2] partial_sort(first, last, last) has the effect of sorting the entire range [first, last), just like sort(first, last). They use different algorithms, however: sort uses the introsort algorithm (a variant of quicksort), and partial_sort uses heapsort. See section 5.2.3 of Knuth (D. E. Knuth, The Art of Computer Programming. Volume 3: Sorting and Searching. Addison-Wesley, 1975.), and J. W. J. Williams (CACM 7, 347, 1964). Both heapsort and introsort have complexity of order N log(N), but introsort is usually faster by a factor of 2 to 5.

See also

partial_sort_copy, sort, stable_sort, binary_search, lower_bound, upper_bound, less<T>, StrictWeakOrdering, LessThan Comparable


partial_sort_copy

Category: algorithms | Component type: function

Prototype

Partial_sort_copy is an overloaded name; there are actually two partial_sort_copy functions.
template <class InputIterator, class RandomAccessIterator>
RandomAccessIterator
partial_sort_copy(InputIterator first, InputIterator last,
                  RandomAccessIterator result_first,
                  RandomAccessIterator result_last);

template <class InputIterator, class RandomAccessIterator,
          class StrictWeakOrdering>
RandomAccessIterator
partial_sort_copy(InputIterator first, InputIterator last,
                  RandomAccessIterator result_first,
                  RandomAccessIterator result_last, Compare comp);

Description

Partial_sort_copy copies the smallest N elements from the range [first, last) to the range [result_first, result_first + N), where N is the smaller of last - first and result_last - result_first. The elements in [result_first, result_first + N) will be in ascending order.

The two versions of partial_sort_copy differ in how they define whether one element is less than another. The first version compares objects using operator<, and the second compares objects using a function object comp.

The postcondition for the first version of partial_sort_copy is as follows. If i and j are any two valid iterators in the range [result_first, result_first + N) such that i precedes j, then *j < *i will be false. The corresponding postcondition for the second version is that comp(*j, *i) will be false.

The return value is result_first + N.

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

For the first version:
  • InputIterator is a model of InputIterator.
  • RandomAccessIterator is a model of Random Access Iterator.
  • RandomAccessIterator is mutable.
  • The value types of InputIterator and RandomAccessIterator are the same.
  • RandomAccessIterator's value type is LessThan Comparable.
  • The ordering relation on RandomAccessIterator's value type is a strict weak ordering, as defined in the LessThan Comparable requirements.
For the second version:
  • InputIterator is a model of InputIterator.
  • RandomAccessIterator is a model of Random Access Iterator.
  • RandomAccessIterator is mutable.
  • The value types of InputIterator and RandomAccessIterator are the same.
  • StrictWeakOrdering is a model of Strict Weak Ordering.
  • RandomAccessIterator's value type is convertible to StrictWeakOrdering's argument type.

Preconditions

  • [first, last) is a valid range.
  • [result_first, result_last) is a valid range.
  • [first, last) and [result_first, result_last) do not overlap.

Complexity

Approximately (last - first) * log(N) comparisons, where N is the smaller of last - first and result_last - result_first.

Example

int A[] = {7, 2, 6, 11, 9, 3, 12, 10, 8, 4, 1, 5};
const int N = sizeof(A) / sizeof(int);

vector<int> V(4);
partial_sort_copy(A, A + N, V.begin(), V.end());
copy(V.begin(), V.end(), ostream_iterator<int>(cout, " "));
// The printed result is "1 2 3 4".

Notes

See also

partial_sort, sort, stable_sort, binary_search, lower_bound, upper_bound, less<T>, StrictWeakOrdering, LessThan Comparable


partial_sum

Category: algorithms | Component type: function

Prototype

Partial_sum is an overloaded name; there are actually two partial_sum functions.
template <class InputIterator, class OutputIterator>
OutputIterator partial_sum(InputIterator first, InputIterator last,
                           OutputIterator result);

template <class InputIterator, class OutputIterator, class BinaryOperation>
OutputIterator partial_sum(InputIterator first, InputIterator last,
                           OutputIterator result, BinaryOperation binary_op);

Description

Partial_sum calculates a generalized partial sum: *first is assigned to *result, the sum of *first and *(first + 1) is assigned to *(result + 1), and so on. [1]

More precisely, a running sum is first initialized to *first and assigned to *result. For each iterator i in [first + 1, last), in order from beginning to end, the sum is updated by sum = sum + *i (in the first version) or sum = binary_op(sum, *i) (in the second version) and is assigned to *(result + (i - first)). [2]

Definition

Defined in the standard header numeric, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

For the first version:
  • InputIterator is a model of Input Iterator.
  • OutputIterator is a model of Output Iterator.
  • If x and y are objects of InputIterator's value type, then x + y is defined.
  • The return type of x + y is convertible to InputIterator's value type.
  • InputIterator's value type is convertible to a type in OutputIterator's set of value types.
For the second version:
  • InputIterator is a model of Input Iterator.
  • OutputIterator is a model of Output Iterator.
  • BinaryFunction is a model of BinaryFunction.
  • InputIterator's value type is convertible to BinaryFunction's first argument type and second argument type.
  • BinaryFunction's result type is convertible to InputIterator's value type.
  • InputIterator's value type is convertible to a type in OutputIterator's set of value types.

Preconditions

  • [first, last) is a valid range.
  • [result, result + (last - first)) is a valid range.

Complexity

Linear. Zero applications of the binary operation if [first, last) is a empty range, otherwise exactly (last - first) - 1 applications.

Example

int main()
{
  const int N = 10;
  int A[N];

  fill(A, A+N, 1);
  cout << "A:                 ";
  copy(A, A+N, ostream_iterator<int>(cout, " "));
  cout << endl;

  cout << "Partial sums of A: ";
  partial_sum(A, A+N, ostream_iterator<int>(cout, " "));
  cout << endl;
}

Notes

[1] Note that result is permitted to be the same iterator as first. This is useful for computing partial sums "in place".

[2] The binary operation is not required to be either associative or commutative: the order of all operations is specified.

See also

adjacent_difference, accumulate, inner_product, count


partition

Category: algorithms | Component type: function

Prototype

template <class ForwardIterator, class Predicate>
ForwardIterator partition(ForwardIterator first,
                          ForwardIterator last, Predicate pred)

Description

Partition reorders the elements in the range [first, last) based on the function object pred, such that the elements that satisfy pred precede the elements that fail to satisfy it. The postcondition is that, for some iterator middle in the range [first, last), pred(*i) is true for every iterator i in the range [first, middle) and false for every iterator i in the range [middle, last). [1] The return value of partition is middle.

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

  • ForwardIterator is a model of Forward Iterator.
  • Predicate is a model of Predicate.
  • ForwardIterator's value type is convertible to Predicate's argument type.

Preconditions

  • [first, last) is a valid range.

Complexity

Linear. Exactly last - first applications of pred, and at most (last - first)/2 swaps.

Example

Reorder a sequence so that even numbers precede odd numbers.
int A[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
const int N = sizeof(A)/sizeof(int);
partition(A, A + N,
          compose1(bind2nd(equal_to<int>(), 0),
                   bind2nd(modulus<int>(), 2)));
copy(A, A + N, ostream_iterator<int>(cout, " "));
// The output is "10 2 8 4 6 5 7 3 9 1". [1]

Notes

[1] The relative order of elements in these two blocks is not necessarily the same as it was in the original sequence. A different algorithm, stable_partition, does guarantee to preserve the relative order.

See also

stable_partition, Predicate, function object


plus<T>

Category: functors | Component type: type

Description

Plus<T> is a function object. Specifically, it is an Adaptable Binary Function. If f is an object of class plus<T> and x and y are objects of class T, then f(x,y) returns x+y.

Example

Each element in V3 will be the sum of the corresponding elements in V1 and V2
const int N = 1000;
vector<double> V1(N);
vector<double> V2(N);
vector<double> V3(N);

iota(V1.begin(), V1.end(), 1);
fill(V2.begin(), V2.end(), 75);

assert(V2.size() >= V1.size() && V3.size() >= V1.size());
transform(V1.begin(), V1.end(), V2.begin(), V3.begin(),
          plus<double>());

Definition

Defined in the standard header functional, and in the nonstandard backward-compatibility header function.h.

Template parameters

Parameter | Description | Default
T | The function object's argument type and result type. |

Model of

Adaptable Binary Function, Default Constructible

Type requirements

T must be a numeric type; if x and y are objects of type T, then x+y must be defined and must have a return type that is convertible to T. T must be Assignable.

Public base classes

binary_function<T, T, T>

Members

Member | Where defined | Description
first_argument_type | Adaptable Binary Function | The type of the first argument: T
second_argument_type | Adaptable Binary Function | The type of the second argument: T
result_type | Adaptable Binary Function | The type of the result: T
T operator()(const T& x, const T& y) | Adaptable Binary Function | Function call operator. The return value is x + y.
plus() | Default Constructible | The default constructor.

New members

All of plus's members are defined in the Adaptable Binary Function and Default Constructible requirements. Plus does not introduce any new members.

Notes

See also

The Function Object overview, Adaptable Binary Function, binary_function, minus, multiplies, divides, modulus, negate


pointer_to_binary_function<Arg1, Arg2, Result>

Categories: functors, adaptors | Component type: type

Description

Pointer_to_binary_function is a function object adaptor that allows a function pointer Result (*f)(Arg1, Arg2) to be treated as an Adaptable Binary Function. That is: if F is a pointer_to_binary_function<Arg1, Arg2, Result> that was initialized with an underlying function pointer f of type Result (*)(Arg1, Arg2), then F(x, y) calls the function f(x, y). The difference between f and F is that pointer_to_binary_function is an Adaptable Binary Function, i.e. it defines the nested typedefs first_argument_type, second_argument_type, and result_type.

Note that a function pointer of type Result (*)(Arg1, Arg2) is a perfectly good Binary Function object, and may be passed to an STL algorithm that expects an argument that is a Binary Function. The only reason for using the pointer_to_binary_function class is if you need to use an ordinary function in a context that requires an Adaptable Binary Function, e.g. as the argument of a function object adaptor.

Most of the time, you need not declare an object of type pointer_to_binary_function directly. It is almost always easier to construct one using the ptr_fun function.

Example

The following code fragment finds the first string in a list that is equal to "OK". It uses the standard library function strcmp as an argument to a function object adaptor, so it must first use a pointer_to_binary_function adaptor to give strcmp the Adaptable Binary Function interface.
list<char*> L;
...
list<char*>::iterator item =
              find_if(L.begin(), L.end(),
                      not1(binder2nd(ptr_fun(strcmp), "OK")));

Definition

Defined in the standard header functional, and in the nonstandard backward-compatibility header function.h.

Template parameters

Parameter | Description | Default
Arg1 | The function object's first argument type |
Arg2 | The function object's second argument type |
Result | The function object's result type |

Model of

Adaptable Binary Function

Type requirements

  • Arg1 is Assignable.
  • Arg2 is Assignable.
  • Result is Assignable.

Public base classes

binary_function<Arg1, Arg2, Result>

Members

Member | Where defined | Description
first_argument_type | Adaptable Binary Function | The type of the first argument: Arg1.
second_argument_type | Adaptable Binary Function | The type of the second argument: Arg2
result_type | Adaptable Binary Function | The type of the result: Result
Result operator()(Arg1 x, Arg2 y) | Binary Function | Function call operator.
pointer_to_binary_function(Result (*f)(Arg1, Arg2)) | pointer_to_binary_function | See below.
pointer_to_binary_function() | pointer_to_binary_function | See below.
template <class Arg1, class Arg2, class Result>
pointer_to_unary_function<Arg1, Arg2, Result>
ptr_fun(Result (*x)(Arg1, Arg2));
pointer_to_binary_function See below.

New members

These members are not defined in the Adaptable Binary Function requirements, but are specific to pointer_to_binary_function.
Member | Description
pointer_to_binary_function(Result (*f)(Arg1, Arg2)) | The constructor. Creates a pointer_to_binary_function whose underlying function is f.
pointer_to_binary_function() | The default constructor. This creates a pointer_to_binary_function that does not have an underlying function, and that therefore cannot actually be called.
template <class Arg1, class Arg2, class Result>
pointer_to_unary_function<Arg1, Arg2, Result>
ptr_fun(Result (*x)(Arg1, Arg2));
If f is of type Result (*)(Arg1, Arg2) then ptr_fun(f) is equivalent to pointer_to_binary_function<Arg1,Arg2,Result>(f), but more convenient. This is a global function, not a member function.

Notes

See also

pointer_to_unary_function, ptr_fun, Adaptable Binary Function


pointer_to_unary_function<Arg, Result>

Categories: functors, adaptors | Component type: type

Description

Pointer_to_unary_function is a function object adaptor that allows a function pointer Result (*f)(Arg) to be treated as an Adaptable Unary Function. That is: if F is a pointer_to_unary_function<Arg, Result> that was initialized with an underlying function pointer f of type Result (*)(Arg), then F(x) calls the function f(x). The difference between f and F is that pointer_to_unary_function is an Adaptable Unary Function, i.e. it defines the nested typedefs argument_type and result_type.

Note that a function pointer of type Result (*)(Arg) is a perfectly good Unary Function object, and may be passed to an STL algorithm that expects an argument that is a Unary Function. The only reason for using the pointer_to_unary_function object is if you need to use an ordinary function in a context that requires an Adaptable Unary Function, e.g. as the argument of a function object adaptor.

Most of the time, you need not declare an object of type pointer_to_unary_function directly. It is almost always easier to construct one using the ptr_fun function.

Example

The following code fragment replaces all of the numbers in a range with their absolute values, using the standard library function fabs. There is no need to use a pointer_to_unary_function adaptor in this case.
transform(first, last, first, fabs);
The following code fragment replaces all of the numbers in a range with the negative of their absolute values. In this case we are composing fabs and negate. This requires that fabs be treated as an adaptable unary function, so we do need to use a pointer_to_unary_function adaptor.
transform(first, last, first,
          compose1(negate<double>, ptr_fun(fabs)));

Definition

Defined in the standard header functional, and in the nonstandard backward-compatibility header function.h.

Template parameters

Parameter | Description | Default
Arg | The function object's argument type |
Result | The function object's result type |

Model of

Adaptable Unary Function

Type requirements

  • Arg is Assignable.
  • Result is Assignable.

Public base classes

unary_function<Arg, Result>

Members

Member | Where defined | Description
argument_type | Adaptable Unary Function | The type of the function object's argument: Arg.
result_type | Adaptable Unary Function | The type of the result: Result
result_type operator()(argument_type x) | Unary Function | Function call operator.
pointer_to_unary_function(Result (*f)(Arg)) | pointer_to_unary_function | See below.
pointer_to_unary_function() | pointer_to_unary_function | See below.
template <class Arg, class Result>
pointer_to_unary_function<Arg, Result>
ptr_fun(Result (*x)(Arg));
pointer_to_unary_function See below.

New members

These members are not defined in the Adaptable Unary Function requirements, but are specific to pointer_to_unary_function.
Member | Description
pointer_to_unary_function(Result (*f)(Arg)) | The constructor. Creates a pointer_to_unary_function whose underlying function is f.
pointer_to_unary_function() | The default constructor. This creates a pointer_to_unary_function that does not have an underlying C function, and that therefore cannot actually be called.
template <class Arg, class Result>
pointer_to_unary_function<Arg, Result>
ptr_fun(Result (*x)(Arg));
If f is of type Result (*)(Arg) then ptr_fun(f) is equivalent to pointer_to_unary_function<Arg,Result>(f), but more convenient. This is a global function, not a member.

Notes

See also

pointer_to_binary_function, ptr_fun, Adaptable Unary Function


pop_heap

Category: algorithms | Component type: function

Prototype

Pop_heap is an overloaded name; there are actually two pop_heap functions.
template <class RandomAccessIterator>
void pop_heap(RandomAccessIterator first, RandomAccessIterator last);

template <class RandomAccessIterator, class StrictWeakOrdering>
inline void pop_heap(RandomAccessIterator first, RandomAccessIterator last,
                     StrictWeakOrdering comp);

Description

Pop_heap removes the largest element (that is, *first) from the heap [1] [first, last). The two versions of pop_heap differ in how they define whether one element is less than another. The first version compares objects using operator<, and the second compares objects using a function object comp.

The postcondition for the first version of pop_heap is that is_heap(first, last-1) is true and that *(last - 1) is the element that was removed from the heap. The postcondition for the second version is that is_heap(first, last-1, comp) is true and that *(last - 1) is the element that was removed from the heap. [2]

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

For the first version:
  • RandomAccessIterator is a model of Random Access Iterator.
  • RandomAccessIterator is mutable.
  • RandomAccessIterator's value type is a model of LessThan Comparable.
  • The ordering on objects of RandomAccessIterator's value type is a strict weak ordering, as defined in the LessThan Comparable requirements.
For the second version:
  • RandomAccessIterator is a model of Random Access Iterator.
  • RandomAccessIterator is mutable.
  • StrictWeakOrdering is a model of Strict Weak Ordering.
  • RandomAccessIterator's value type is convertible to StrictWeakOrdering's argument type.

Preconditions

For the first version:
  • [first, last) is a valid range.
  • [first, last - 1) is a valid range. That is, [first, last) is nonempty.
  • [first, last) is a heap. That is, is_heap(first, last) is true.
For the second version:
  • [first, last) is a valid range.
  • [first, last - 1) is a valid range. That is, [first, last) is nonempty.
  • [first, last) is a heap. That is, is_heap(first, last, comp) is true.

Complexity

Logarithmic. At most 2 * log(last - first) comparisons.

Example

int main()
{
  int A[] = {1, 2, 3, 4, 5, 6};
  const int N = sizeof(A) / sizeof(int);

  make_heap(A, A+N);
  cout << "Before pop: ";
  copy(A, A+N, ostream_iterator<int>(cout, " "));

  pop_heap(A, A+N);
  cout << endl << "After pop: ";
  copy(A, A+N-1, ostream_iterator<int>(cout, " "));
  cout << endl << "A[N-1] = " << A[N-1] << endl;
}

The output is

Before pop: 6 5 3 4 2 1
After pop: 5 4 3 1 2
A[N-1] = 6

Notes

[1] A heap is a particular way of ordering the elements in a range of Random Access Iterators [f, l). The reason heaps are useful (especially for sorting, or as priority queues) is that they satisfy two important properties. First, *f is the largest element in the heap. Second, it is possible to add an element to a heap (using push_heap), or to remove *f, in logarithmic time. Internally, a heap is a tree represented as a sequential range. The tree is constructed so that that each node is less than or equal to its parent node.

[2] Pop_heap removes the largest element from a heap, and shrinks the heap. This means that if you call keep calling pop_heap until only a single element is left in the heap, you will end up with a sorted range where the heap used to be. This, in fact, is exactly how sort_heap is implemented.

See also

make_heap, push_heap, sort_heap, is_heap, sort


power

Category: algorithms | Component type: function

Prototype

Power is an overloaded name; there are actually two power functions.
template <class T, class Integer>
inline T power(T x, Integer n);

template <class T, class Integer, class MonoidOperation>
T power(T x, Integer n, MonoidOperation op);

Description

Power is generalized exponentiation: it raises the value x to the power n, where n is a non-negative integer.

The first version of power returns x raised to the nth power; that is, it returns x * x ... * x, where x is repeated n times. [1] If n == 0, then it returns identity_element(multiplies<T>()).

The second version of power is just like the first except that it uses an arbitrary Monoid Operation instead of multiplies<T>, returning identity_element(op) when n == 0.

Important note: power does not assume that multiplication is commutative, but it does rely crucially on the fact that multiplication is associative. If you have defined * or MonoidOperation to be a non-associative operation, then power will give you the wrong answer. [2]

Definition

Defined in the standard header numeric, and in the nonstandard backward-compatibility header algo.h. This function is an SGI extension; it is not part of the C++ standard.

Requirements on types

For the first version:
  • multiplies<T> is a model of Monoid Operation.
  • Integer is an integral type.
For the second version:
  • MonoidOperation is a model of Monoid Operation.
  • T is MonoidOperation's argument type.
  • n is an integral type.

Preconditions

  • n >= 0.

Complexity

The number of multiplications (or, in the case of the second version, the number of applications of MonoidOperation) is lg(n) + nu(n) where lg is the base 2 logarithm and nu(n) is the number of 1s in the binary representation of n. [3]

Example

int main() {
  cout << "2 ** 30 = " << power(2, 30) << endl;
}

Notes

[1] This is a conceptual description of what power's return value is; it is not how power is actually implemented. If power were implemented that way then it would require n-1 multiplications, which would be grossly inefficient. Power is implemented using the "Russian peasant algorithm", which requires only O(log n) multiplications. See section 4.6.3 of Knuth (D. E. Knuth, The Art of Computer Programming. Volume 2: Seminumerical Algorithms, Addison-Wesley, 1981) for a discussion.

[2] See the Monoid Operation requirements for a discussion of associativity.

[3] This is in fact not the minimum possible number of multiplications: it is possible to compute the fifteenth power of x using only five multiplications, but power(x, 15) uses six.

See also

Monoid Operation, multiplies, plus


Predicate

Category: functors | Component type: concept

Description

A Predicate is a Unary Function whose result represents the truth or falsehood of some condition. A Predicate might, for example, be a function that takes an argument of type int and returns true if the argument is positive.

Refinement of

Unary Function

Associated types

Result type The type returned when the Predicate is called. The result type must be convertible to bool.

Notation

F | A type that is a model of Predicate
X | The argument type of F
f | Object of type F
x | Object of type X

Valid expressions

Name | Expression | Type requirements | Return type
Function call | f(x) |  | Convertible to bool

Expression semantics

Name | Expression | Precondition | Semantics | Postcondition
Function call | f(x) | x is in the domain of f. | Returns true if the condition is satisfied, false if it is not. | The result is either true or false.

Complexity guarantees

Invariants

Models

  • bool (*)(int)

Notes

See also

Adaptable Predicate, Binary Predicate, Adaptable Binary Predicate


prev_permutation

Category: algorithms | Component type: function

Prototype

Prev_permutation is an overloaded name; there are actually two prev_permutation functions.
template <class BidirectionalIterator>
bool prev_permutation(BidirectionalIterator first,
                      BidirectionalIterator last);

template <class BidirectionalIterator, class StrictWeakOrdering>
bool prev_permutation(BidirectionalIterator first, BidirectionalIterator last,
                      StrictWeakOrdering comp);

Description

Prev_permutation transforms the range of elements [first, last) into the lexicographically next smaller permutation of the elements. There is a finite number of distinct permutations (at most N! [1], where N is last - first), so, if the permutations are ordered by lexicographical_compare, there is an unambiguous definition of which permutation is lexicographically previous. If such a permutation exists, prev_permutation transforms [first, last) into that permutation and returns true. Otherwise it transforms [first, last) into the lexicographically greatest permutation [2] and returns false.

The postcondition is that the new permutation of elements is lexicographically less than the old (as determined by lexicographical_compare) if and only if the return value is true.

The two versions of prev_permutation differ in how they define whether one element is less than another. The first version compares objects using operator<, and the second compares objects using a function object comp.

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

For the first version:
  • BidirectionalIterator is a model of Bidirectional Iterator.
  • BidirectionalIterator is mutable.
  • BidirectionalIterator's value type is LessThan Comparable.
  • The ordering relation on BidirectionalIterator's value type is a strict weak ordering, as defined in the LessThan Comparable requirements.
For the second version:
  • BidirectionalIterator is a model of Bidirectional Iterator.
  • BidirectionalIterator is mutable.
  • StrictWeakOrdering is a model of Strict Weak Ordering.
  • BidirectionalIterator's value type is convertible to StrictWeakOrdering's argument type.

Preconditions

  • [first, last) is a valid range.

Complexity

Linear. At most (last - first) / 2 swaps.

Example

int main()
{
  int A[] = {2, 3, 4, 5, 6, 1};
  const int N = sizeof(A) / sizeof(int);

  cout << "Initially:              ";
  copy(A, A+N, ostream_iterator<int>(cout, " "));
  cout << endl;

  prev_permutation(A, A+N);
  cout << "After prev_permutation: ";
  copy(A, A+N, ostream_iterator<int>(cout, " "));
  cout << endl;

  next_permutation(A, A+N);
  cout << "After next_permutation: ";
  copy(A, A+N, ostream_iterator<int>(cout, " "));
  cout << endl;
}

Notes

[1] If all of the elements in [first, last) are distinct from each other, then there are exactly N! permutations. If some elements are the same as each other, though, then there are fewer. There are, for example, only three (3!/2!) permutations of the elements 1 1 2.

[2] Note that the lexicographically greatest permutation is, by definition, sorted in nonascending order.

See also

next_permutation, lexicographical_compare, LessThan Comparable, Strict Weak Ordering, sort


priority_queue<T, Sequence, Compare>

Categories: containers, adaptors | Component type: type

Description

A priority_queue is an adaptor that provides a restricted subset of Container functionality: it provides insertion of elements, and inspection and removal of the top element. It is guaranteed that the top element is the largest element in the priority_queue, where the function object Compare is used for comparisons. [1] Priority_queue does not allow iteration through its elements. [2]

Priority_queue is a container adaptor, meaning that it is implemented on top of some underlying container type. By default that underlying type is vector, but a different type may be selected explicitly.

Example

int main() {
  priority_queue<int> Q;
  Q.push(1);
  Q.push(4);
  Q.push(2);
  Q.push(8);
  Q.push(5);
  Q.push(7);

  assert(Q.size() == 6);

  assert(Q.top() == 8);
  Q.pop();

  assert(Q.top() == 7);
  Q.pop();

  assert(Q.top() == 5);
  Q.pop();

  assert(Q.top() == 4);
  Q.pop();

  assert(Q.top() == 2);
  Q.pop();

  assert(Q.top() == 1);
  Q.pop();

  assert(Q.empty());
}

Definition

Defined in the standard header queue, and in the nonstandard backward-compatibility header stack.h.

Template parameters

Parameter | Description | Default
T | The type of object stored in the priority queue. |
Sequence | The type of the underlying container used to implement the priority queue. | vector<T>
Compare | The comparison function used to determine whether one element is smaller than another element. If Compare(x,y) is true, then x is smaller than y. The element returned by Q.top() is the largest element in the priority queue. That is, it has the property that, for every other element x in the priority queue, Compare(Q.top(), x) is false. | less<T>

Model of

Assignable, Default Constructible

Type requirements

  • T is a model of Assignable.
  • Sequence is a model of Sequence.
  • Sequence is a model of Random Access Container
  • Sequence::value_type is the same type as T.
  • Compare is a model of Binary Predicate
  • Compare induces a strict weak ordering, as defined in the LessThan Comparable requirements, on its argument type.
  • T is convertible to Compare's argument type.

Public base classes

None.

Members

Member | Where defined | Description
value_type | priority_queue | See below.
size_type | priority_queue | See below.
priority_queue() | Default Constructible | The default constructor. Creates an empty priority_queue, using Compare() as the comparison function.
priority_queue(const priority_queue&) | Assignable | The copy constructor.
priority_queue(const Compare&) | priority_queue | See below.
priority_queue(const value_type*,
               const value_type*)
priority_queue See below.
priority_queue(const value_type*,
               const value_type*,
               const Compare&)
priority_queue See below.
priority_queue&
operator=(const priority_queue&)
Assignable The assignment operator.
bool empty() const | priority_queue | See below.
size_type size() const | priority_queue | See below.
const value_type& top() const | priority_queue | See below.
void push(const value_type&) | priority_queue | See below.
void pop() [3] | priority_queue | See below.

New members

These members are not defined in the Assignable and Default Constructible requirements, but are specific to priority_queue.
Member | Description
value_type | The type of object stored in the priority_queue. This is the same as T and Sequence::value_type.
size_type | An unsigned integral type. This is the same as Sequence::size_type.
priority_queue(const Compare& comp) | The constructor. Creates an empty priority_queue, using comp as the comparison function. The default constructor uses Compare() as the comparison function.
priority_queue(const value_type* first,
               const value_type* last)
The constructor. Creates a priority_queue initialized to contain the elements in the range [first, last), and using Compare() as the comparison function.
priority_queue(const value_type* first,
               const value_type* last,
               const Compare& comp)
The constructor. Creates a priority_queue initialized to contain the elements in the range [first, last), and using comp as the comparison function.
bool empty() const | Returns true if the priority_queue contains no elements, and false otherwise. S.empty() is equivalent to S.size() == 0.
size_type size() const | Returns the number of elements contained in the priority_queue.
const value_type& top() const | Returns a const reference to the element at the top of the priority_queue. The element at the top is guaranteed to be the largest element in the priority queue, as determined by the comparison function Compare. That is, for every other element x in the priority_queue, Compare(Q.top(), x) is false. Precondition: empty() is false.
void push(const value_type& x) | Inserts x into the priority_queue. Postcondition: size() will be incremented by 1.
void pop() | Removes the element at the top of the priority_queue, that is, the largest element in the priority_queue. [3] Precondition: empty() is false. Postcondition: size() will be decremented by 1.

Notes

[1] Priority queues are a standard concept, and can be implemented in many different ways; this implementation uses heaps. Priority queues are discussed in all algorithm books; see, for example, section 5.2.3 of Knuth. (D. E. Knuth, The Art of Computer Programming. Volume 3: Sorting and Searching. Addison-Wesley, 1975.)

[2] This restriction is the only reason for priority_queue to exist at all. If iteration through elements is important, you can either use a vector that is maintained in sorted order, or a set, or a vector that is maintained as a heap using make_heap, push_heap, and pop_heap. Priority_queue is, in fact, implemented as a random access container that is maintained as a heap. The only reason to use the container adaptor priority_queue, instead of performing the heap operations manually, is to make it clear that you are never performing any operations that might violate the heap invariant.

[3] One might wonder why pop() returns void, instead of value_type. That is, why must one use top() and pop() to examine and remove the element at the top of the priority_queue, instead of combining the two in a single member function? In fact, there is a good reason for this design. If pop() returned the top element, it would have to return by value rather than by reference: return by reference would create a dangling pointer. Return by value, however, is inefficient: it involves at least one redundant copy constructor call. Since it is impossible for pop() to return a value in such a way as to be both efficient and correct, it is more sensible for it to return no value at all and to require clients to use top() to inspect the value at the top of the priority_queue.

See also

stack, queue, set, make_heap, push_heap, pop_heap, is_heap, sort, is_sorted, Container, Sorted Associative Container, Sequence


project1st<Arg1, Arg2>

Category: functors | Component type: type

Description

Project1st is a function object that takes two arguments and returns its first argument; the second argument is unused. It is essentially a generalization of identity to the case of a Binary Function.

Example

int main()
{
  vector<int> v1(10, 137);
  vector<char*> v2(10, (char*) 0);
  vector<int> result(10);

  transform(v1.begin(), v1.end(), v2.begin(), result.begin(),
            project1st<int, char*>());
  assert(equal(v1.begin(), v1.end(), result.begin()));
}

Definition

Defined in the standard header functional, and in the nonstandard backward-compatibility header function.h. This function object is an SGI extension; it is not part of the C++ standard.

Template parameters

Parameter | Description | Default
Arg1 | project1st's first argument type, and its result type. |
Arg2 | project1st's second argument type. |

Model of

Adaptable Binary Function

Type requirements

None.

Public base classes

binary_function<Arg1, Arg2, Arg1>

Members

Member | Where defined | Description
first_argument_type | Adaptable Binary Function | The type of project1st's first argument: Arg1
second_argument_type | Adaptable Binary Function | The type of project1st's second argument: Arg2
result_type | Adaptable Binary Function | The type of the result: Arg1.
Arg1 operator()(const Arg1& x, const Arg2&) const | Adaptable Binary Function | Function call. The return value is x.

New members

All of project1st's members are defined in the Adaptable Binary Function requirements. project1st does not introduce any new members.

Notes

See also

Function objects, identity, project2nd, select1st, select2nd


project2nd<Arg1, Arg2>

Category: functors | Component type: type

Description

Project2nd is a function object that takes two arguments and returns its second argument; the first argument is unused. It is essentially a generalization of identity to the case of a Binary Function.

Example

int main()
{
  vector<char*> v1(10, (char*) 0);
  vector<int> v2(10, 137);
  vector<int> result(10);

  transform(v1.begin(), v1.end(), v2.begin(), result.begin(),
            project2nd<char*, int>());
  assert(equal(v2.begin(), v2.end(), result.begin()));
}

Definition

Defined in the standard header functional, and in the nonstandard backward-compatibility header function.h. This function object is an SGI extension; it is not part of the C++ standard.

Template parameters

Parameter | Description | Default
Arg1 | project2nd's first argument type. |
Arg2 | project2nd's second argument type, and its result type. |

Model of

Adaptable Binary Function

Type requirements

None.

Public base classes

binary_function<Arg1, Arg2, Arg2>

Members

Member | Where defined | Description
first_argument_type | Adaptable Binary Function | The type of project2nd's first argument: Arg1
second_argument_type | Adaptable Binary Function | The type of project2nd's second argument: Arg2
result_type | Adaptable Binary Function | The type of the result: Arg2.
Arg1 operator()(const Arg1&, const Arg2& y) const | Adaptable Binary Function | Function call. The return value is y.

New members

All of project2nd's members are defined in the Adaptable Binary Function requirements. project2nd does not introduce any new members.

Notes

See also

Function objects, identity, project1st, select1st, select2nd


ptr_fun

Categories: functors, adaptors | Component type: function

Prototype

template <class Arg, class Result>
pointer_to_unary_function<Arg, Result>
ptr_fun(Result (*x)(Arg));

template <class Arg1, class Arg2, class Result>
pointer_to_binary_function<Arg1, Arg2, Result>
ptr_fun(Result (*x)(Arg1, Arg2));

Description

Ptr_fun takes a function pointer as its argument and returns a function pointer adaptor, a type of function object. It is actually two different functions, not one (that is, the name ptr_fun is overloaded). If its argument is of type Result (*)(Arg) then ptr_fun creates a pointer_to_unary_function, and if its argument is of type Result (*)(Arg1, Arg2) then ptr_fun creates a pointer_to_binary_function.

Definition

Defined in the standard header functional, and in the nonstandard backward-compatibility header function.h.

Requirements on types

The argument must be a pointer to a function that takes either one or two arguments. The argument type(s) and the return type of the function are arbitrary, with the restriction that the function must return a value; it may not be a void function.

Preconditions

Complexity

Example

See the examples in the discussions of pointer_to_unary_function and pointer_to_binary_function.

Notes

See also

Function Objects, pointer_to_unary_function, pointer_to_binary_function, Adaptable Unary Function, Adaptable Binary Function


push_heap

Category: algorithms | Component type: function

Prototype

Push_heap is an overloaded name; there are actually two push_heap functions.
template <class RandomAccessIterator>
void push_heap(RandomAccessIterator first, RandomAccessIterator last);

template <class RandomAccessIterator, class StrictWeakOrdering>
void push_heap(RandomAccessIterator first, RandomAccessIterator last,
               StrictWeakOrdering comp);

Description

Push_heap adds an element to a heap [1]. It is assumed that [first, last - 1) is already a heap; the element to be added to the heap is *(last - 1).

The two versions of push_heap differ in how they define whether one element is less than another. The first version compares objects using operator<, and the second compares objects using a function object comp. The postcondition for the first version is that is_heap(first, last) is true, and the postcondition for the second version is that is_heap(first, last, comp) is true.

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

For the first version:
  • RandomAccessIterator is a model of Random Access Iterator.
  • RandomAccessIterator is mutable.
  • RandomAccessIterator's value type is a model of LessThan Comparable.
  • The ordering on objects of RandomAccessIterator's value type is a strict weak ordering, as defined in the LessThan Comparable requirements.
For the second version:
  • RandomAccessIterator is a model of Random Access Iterator.
  • RandomAccessIterator is mutable.
  • StrictWeakOrdering is a model of Strict Weak Ordering.
  • RandomAccessIterator's value type is convertible to StrictWeakOrdering's argument type.

Preconditions

For the first version:
  • [first, last) is a valid range.
  • [first, last - 1) is a valid range. That is, [first, last) is nonempty.
  • [first, last - 1) is a heap. That is, is_heap(first, last - 1) is true.
For the second version:
  • [first, last) is a valid range.
  • [first, last - 1) is a valid range. That is, [first, last) is nonempty.
  • [first, last) is a heap. That is, is_heap(first, last - 1, comp) is true.

Complexity

Logarithmic. At most log(last - first) comparisons.

Example

int main()
{
  int A[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

  make_heap(A, A + 9);
  cout << "[A, A + 9)  = ";
  copy(A, A + 9, ostream_iterator<int>(cout, " "));

  push_heap(A, A + 10);
  cout << endl << "[A, A + 10) = ";
  copy(A, A + 10, ostream_iterator<int>(cout, " "));
  cout << endl;
}

The output is

[A, A + 9)  = 8 7 6 3 4 5 2 1 0
[A, A + 10) = 9 8 6 3 7 5 2 1 0 4

Notes

[1] A heap is a particular way of ordering the elements in a range of random access iterators [f, l). The reason heaps are useful (especially for sorting, or as priority queues) is that they satisfy two important properties. First, *f is the largest element in the heap. Second, it is possible to add an element to a heap (using push_heap), or to remove *f, in logarithmic time. Internally, a heap is a tree represented as a sequential range. The tree is constructed so that that each node is less than or equal to its parent node.

See also

make_heap, pop_heap, sort_heap, is_heap, sort


queue<T, Sequence>

Categories: containers, adaptors | Component type: type

Description

A queue is an adaptor that provides a restricted subset of Container functionality A queue is a "first in first out" (FIFO) data structure. [1] That is, elements are added to the back of the queue and may be removed from the front; Q.front() is the element that was added to the queue least recently. Queue does not allow iteration through its elements. [2]

Queue is a container adaptor, meaning that it is implemented on top of some underlying container type. By default that underlying type is deque, but a different type may be selected explicitly.

Example

int main() {
  queue<int> Q;
  Q.push(8);
  Q.push(7);
  Q.push(6);
  Q.push(2);

  assert(Q.size() == 4);
  assert(Q.back() == 2);

  assert(Q.front() == 8);
  Q.pop();

  assert(Q.front() == 7);
  Q.pop();

  assert(Q.front() == 6);
  Q.pop();

  assert(Q.front() == 2);
  Q.pop();

  assert(Q.empty());
}

Definition

Defined in the standard header queue, and in the nonstandard backward-compatibility header stack.h.

Template parameters

Parameter | Description | Default
T | The type of object stored in the queue. |
Sequence | The type of the underlying container used to implement the queue. | deque<T>

Model of

Assignable, Default Constructible

Type requirements

  • T is a model of Assignable.
  • Sequence is a model of Front Insertion Sequence.
  • Sequence is a model of Back Insertion Sequence.
  • Sequence::value_type is the same type as T.
  • If operator== is used, then T is a model of Equality Comparable
  • If operator< is used, then T is a model of LessThan Comparable.

Public base classes

None.

Members

Member | Where defined | Description
value_type | queue | See below.
size_type | queue | See below.
queue() | Default Constructible | The default constructor. Creates an empty queue.
queue(const queue&) | Assignable | The copy constructor.
queue& operator=(const queue&) | Assignable | The assignment operator.
bool empty() const | queue | See below.
size_type size() const | queue | See below.
value_type& front() | queue | See below.
const value_type& front() const | queue | See below.
value_type& back() | queue | See below.
const value_type& back() const | queue | See below.
void push(const value_type&) | queue | See below.
void pop() [3] | queue | See below.
bool operator==(const queue&, const queue&) | queue | See below.
bool operator<(const queue&, const queue&) | queue | See below.

New members

These members are not defined in the Assignable and Default Constructible requirements, but are specific to queue.
Member | Description
value_type | The type of object stored in the queue. This is the same as T and Sequence::value_type.
size_type | An unsigned integral type. This is the same as Sequence::size_type.
bool empty() const | Returns true if the queue contains no elements, and false otherwise. Q.empty() is equivalent to Q.size() == 0.
size_type size() const | Returns the number of elements contained in the queue.
value_type& front() | Returns a mutable reference to the element at the front of the queue, that is, the element least recently inserted. Precondition: empty() is false.
const value_type& front() const | Returns a const reference to the element at the front of the queue, that is, the element least recently inserted. Precondition: empty() is false.
value_type& back() | Returns a mutable reference to the element at the back of the queue, that is, the element most recently inserted. Precondition: empty() is false.
const value_type& back() const | Returns a const reference to the element at the back of the queue, that is, the element most recently inserted. Precondition: empty() is false.
void push(const value_type& x) | Inserts x at the back of the queue. Postconditions: size() will be incremented by 1, and back() will be equal to x.
void pop() | Removes the element at the front of the queue. [3] Precondition: empty() is false. Postcondition: size() will be decremented by 1.
bool operator==(const queue&, const queue&) | Compares two queues for equality. Two queues are equal if they contain the same number of elements and if they are equal element-by-element. This is a global function, not a member function.
bool operator<(const queue&, const queue&) | Lexicographical ordering of two queues. This is a global function, not a member function.

Notes

[1] Queues are a standard data structure, and are discussed in all algorithm books. See, for example, section 2.2.1 of Knuth. (D. E. Knuth, The Art of Computer Programming. Volume 1: Fundamental Algorithms, second edition. Addison-Wesley, 1973.)

[2] This restriction is the only reason for queue to exist at all. Any container that is both a front insertion sequence and a back insertion sequence can be used as a queue; deque, for example, has member functions front, back, push_front, push_back, pop_front, and pop_back The only reason to use the container adaptor queue instead of the container deque is to make it clear that you are performing only queue operations, and no other operations.

[3] One might wonder why pop() returns void, instead of value_type. That is, why must one use front() and pop() to examine and remove the element at the front of the queue, instead of combining the two in a single member function? In fact, there is a good reason for this design. If pop() returned the front element, it would have to return by value rather than by reference: return by reference would create a dangling pointer. Return by value, however, is inefficient: it involves at least one redundant copy constructor call. Since it is impossible for pop() to return a value in such a way as to be both efficient and correct, it is more sensible for it to return no value at all and to require clients to use front() to inspect the value at the front of the queue.

See also

stack, priority_queue, deque, Container, Sequence


Random Access Container

Category: containers | Component type: concept

Description

A Random Access Container is a Reversible Container whose iterator type is a Random Access Iterator. It provides amortized constant time access to arbitrary elements.

Refinement of

Reversible Container

Associated types

No additional types beyond those defined in Reversible Container. However, the requirements for the iterator type are strengthened: it must be a Random Access Iterator.

Notation

X | A type that is a model of Random Access Container
a, b | Object of type X
T | The value type of X

Definitions

Valid expressions

In addition to the expressions defined in Reversible Container, the following expressions must be valid.
Name | Expression | Type requirements | Return type
Element access | a[n] | n is convertible to size_type | reference if a is mutable, const_reference otherwise

Expression semantics

Semantics of an expression is defined only where it is not defined in Reversible Container, or where there is additional information.
Name | Expression | Precondition | Semantics | Postcondition
Element access | a[n] | 0 <= n < a.size() | Returns the nth element from the beginning of the container. |

Complexity guarantees

The run-time complexity of element access is amortized constant time.

Invariants

Element access The element returned by a[n] is the same as the one obtained by incrementing a.begin() n times and then dereferencing the resulting iterator.

Models

  • vector
  • deque

Notes

See also

The Iterator overview, Random Access Iterator, Sequence


Random Access Iterator

Category: iterators | Component type: concept

Description

A Random Access Iterator is an iterator that provides both increment and decrement (just like a Bidirectional Iterator), and that also provides constant-time methods for moving forward and backward in arbitrary-sized steps. Random Access Iterators provide essentially all of the operations of ordinary C pointer arithmetic.

Refinement of

Bidirectional Iterator, LessThan Comparable

Associated types

The same as for Bidirectional Iterator

Notation

X | A type that is a model of Random Access Iterator
T | The value type of X
Distance | The distance type of X
i, j | Object of type X
t | Object of type T
n | Object of type Distance

Definitions

Valid expressions

In addition to the expressions defined in Bidirectional Iterator, the following expressions must be valid.
Name | Expression | Type requirements | Return type
Iterator addition | i += n |  | X&
Iterator addition | i + n or n + i |  | X
Iterator subtraction | i -= n |  | X&
Iterator subtraction | i - n |  | X
Difference | i - j |  | Distance
Element operator | i[n] |  | Convertible to T
Element assignment | i[n] = t | X is mutable | Convertible to T

Expression semantics

Semantics of an expression is defined only where it differs from, or is not defined in, Bidirectional Iterator or LessThan Comparable.
Name | Expression | Precondition | Semantics | Postcondition
Forward motion | i += n | Including i itself, there must be n dereferenceable or past-the-end iterators following or preceding i, depending on whether n is positive or negative. | If n > 0, equivalent to executing ++i n times. If n < 0, equivalent to executing --i n times. If n == 0, this is a null operation. [1] | i is dereferenceable or past-the-end.
Iterator addition | i + n or n + i | Same as for i += n | Equivalent to { X tmp = i; return tmp += n; }. The two forms i + n and n + i are identical. | Result is dereferenceable or past-the-end
Iterator subtraction | i -= n | Including i itself, there must be n dereferenceable or past-the-end iterators preceding or following i, depending on whether n is positive or negative. | Equivalent to i += (-n). | i is dereferenceable or past-the-end.
Iterator subtraction | i - n | Same as for i -= n | Equivalent to { X tmp = i; return tmp -= n; }. | Result is dereferenceable or past-the-end
Difference | i - j | Either i is reachable from j or j is reachable from i, or both. | Returns a number n such that i == j + n |
Element operator | i[n] | i + n exists and is dereferenceable. | Equivalent to *(i + n) [2] |
Element assignment | i[n] = t | i + n exists and is dereferenceable. | Equivalent to *(i + n) = t [2] | i[n] is a copy of t.
Less | i < j | Either i is reachable from j or j is reachable from i, or both. [3] | As described in LessThan Comparable [4] |

Complexity guarantees

All operations on Random Access Iterators are amortized constant time. [5]

Invariants

Symmetry of addition and subtraction | If i + n is well-defined, then i += n; i -= n; and (i + n) - n are null operations. Similarly, if i - n is well-defined, then i -= n; i += n; and (i - n) + n are null operations.
Relation between distance and addition | If i - j is well-defined, then i == j + (i - j).
Reachability and distance | If i is reachable from j, then i - j >= 0.
Ordering | operator < is a strict weak ordering, as defined in LessThan Comparable.

Models

  • T*
  • vector<T>::iterator
  • vector<T>::const_iterator
  • deque<T>::iterator
  • deque<T>::const_iterator

Notes

[1] "Equivalent to" merely means that i += n yields the same iterator as if i had been incremented (decremented) n times. It does not mean that this is how operator+= should be implemented; in fact, this is not a permissible implementation. It is guaranteed that i += n is amortized constant time, regardless of the magnitude of n. [5]

[2] One minor syntactic oddity: in C, if p is a pointer and n is an int, then p[n] and n[p] are equivalent. This equivalence is not guaranteed, however, for Random Access Iterators: only i[n] need be supported. This isn't a terribly important restriction, though, since the equivalence of p[n] and n[p] has essentially no application except for obfuscated C contests.

[3] The precondition defined in LessThan Comparable is that i and j be in the domain of operator <. Essentially, then, this is a definition of that domain: it is the set of pairs of iterators such that one iterator is reachable from the other.

[4] All of the other comparison operators have the same domain and are defined in terms of operator <, so they have exactly the same semantics as described in LessThan Comparable.

[5] This complexity guarantee is in fact the only reason why Random Access Iterator exists as a distinct concept. Every operation in iterator arithmetic can be defined for Bidirectional Iterators; in fact, that is exactly what the algorithms advance and distance do. The distinction is simply that the Bidirectional Iterator implementations are linear time, while Random Access Iterators are required to support random access to elements in amortized constant time. This has major implications for the sorts of algorithms that can sensibly be written using the two types of iterators.

See also

LessThan Comparable, Trivial Iterator, Bidirectional Iterator, Iterator overview


Random Number Generator

Category: functors | Component type: concept

Description

A Random Number Generator is a function object that can be used to generate a random sequence of integers. That is: if f is a Random Number Generator and N is a positive integer, then f(N) will return an integer less than N and greater than or equal to 0. If f is called many times with the same value of N, it will yield a sequence of numbers that is uniformly distributed [1] in the range [0, N). [2]

Refinement of

Unary Function

Associated types

Argument type | The type of the Random Number Generator's argument. This must be an integral type.
Result type | The type returned when the Random Number Generator is called. It must be the same as the argument type.

Notation

F | A type that is a model of Random Number Generator.
Integer | The argument type of F.
f | Object of type F.
N | Object of type Integer

Definitions

The domain of a Random Number Generator (i.e. the set of permissible values for its argument) is the set of numbers that are greater than zero and less than some maximum value.

The range of a Random Number Generator is the set of nonnegative integers that are less than the Random Number Generator's argument.

Valid expressions

None, except for those defined by Unary Function.

Expression semantics

Name | Expression | Precondition | Semantics | Postcondition
Function call | f(N) | N is positive. | Returns a pseudo-random number of type Integer. [2] | The return value is less than N, and greater than or equal to 0.

Complexity guarantees

Invariants

Uniformity In the limit as f is called many times with the same argument N, every integer in the range [0, N) will appear an equal number of times.

Models

Notes

[1] Uniform distribution means that all of the numbers in the range [0, N) appear with equal frequency. Or, to put it differently, the probability for obtaining any particular value is 1/N.

[2] Random number generators are a very subtle subject: a good random number generator must satisfy many statistical properties beyond uniform distribution. See section 3.4 of Knuth for a discussion of what it means for a sequence to be random, and section 3.2 for several algorithms that may be used to write random number generators. (D. E. Knuth, The Art of Computer Programming. Volume 2: Seminumerical Algorithms, third edition. Addison-Wesley, 1998.)

See also

[Silicon Surf] [STL Home]
Copyright © 1999 Silicon Graphics, Inc. All Rights Reserved. TrademarkInformation


random_access_iterator<T, Distance>

Category: iterators | Component type: type

Description

Random_access_iterator is an iterator base class: it is intended that an iterator that is a model of Random Access Iterator, and whose value type and distance type are T and Distance, may be defined by inheriting from random_access_iterator<T, Distance> [1]. Random_access_iterator is entirely empty: it has no member functions, member variables, or nested types. It exists solely to simplify the definition of the functions iterator_category, distance_type, and value_type.

Example

class my_random_access_iterator : public random_access_iterator<double>
{
  ...
};
This declares my_random_access_iterator to be a Random Access Iterator whose value type is double and whose distance type is ptrdiff_t. If Iter is an object of class my_random_access_iterator, then iterator_category(Iter) will return random_access_iterator_tag(), value_type(Iter) will return (double*) 0, and distance_type(Iter) will return (ptrdiff_t*) 0.

Definition

Defined in the standard header iterator, and in the nonstandard backward-compatibility header iterator.h. This class is no longer part of the C++ standard, although it was present in early drafts of the standard. It is retained in this implementation for backward compatibility.

Template parameters

Parameter | Description | Default
T | The iterator's value type |
Distance | The iterator's distance type | ptrdiff_t

Model of

Assignable

Public base classes

None

Type requirements

The distance type must be a signed integral type.

Public base classes

None.

Members

None.

New Members

None.

Notes

[1] It is not required that a Random Access Iterator inherit from the base random_access_iterator. It is, however, required that the functions iterator_category, distance_type, and value_type be defined for every Random Access Iterator. (Or, if you are using the iterator_traits mechanism, that iterator_traits is properly specialized for every Random Access Iterator.) Since those functions are defined for the base random_access_iterator, the easiest way to ensure that are defined for a new type is to derive that class from random_access_iterator and rely on the derived-to-base standard conversion of function arguments.

See also

The Iterator Tags overview, iterator_traits, iterator_category, value_type, distance_type, input_iterator, output_iterator, forward_iterator, bidirectional_iterator


random_access_iterator_tag

Category: iterators | Component type: type

Description

Random_access_iterator_tag is an empty class: it has no member functions, member variables, or nested types. It is used solely as a "tag": a representation of the Random Access Iterator concept within the C++ type system. Specifically, it is used as a return value for the function iterator_category. Iterator_category takes a single argument, an iterator, and returns an object whose type depends on the iterator's category. Iterator_category's return value is of type random_access_iterator_tag if its argument is a Random Access Iterator.

Example

See iterator_category

Definition

Defined in the standard header iterator, and in the nonstandard backward-compatibility header iterator.h.

Template parameters

None.

Model of

Assignable

Type requirements

None.

Public base classes

None.

Members

None.

New Members

None.

Notes

See also

iterator_category, Iterator Tags, iterator_traits, output_iterator_tag, input_iterator_tag, forward_iterator_tag, bidirectional_iterator_tag


random_sample

Category: algorithms | Component type: function

Prototype

Random_sample is an overloaded name; there are actually two random_sample functions.
template <class InputIterator, class RandomAccessIterator>
Random AccessIterator
random_sample(InputIterator first, InputIterator last,
          RandomAccessIterator ofirst, RandomAccessIterator olast)

template <class InputIterator, class RandomAccessIterator,
      class RandomNumberGenerator>
random_sample(InputIterator first, InputIterator last,
          RandomAccessIterator ofirst, RandomAccessIterator olast,
          RandomNumberGenerator& rand)

Description

Random_sample randomly copies a sample of the elements from the range [first, last) into the range [ofirst, olast). Each element in the input range appears at most once in the output range, and samples are chosen with uniform probability. [1] Elements in the output range might appear in any order: relative order within the input range is not guaranteed to be preserved. [2]

Random_sample copies n elements from [first, last) to [ofirst, olast), where n is min(last - first, olast - ofirst). The return value is ofirst + n.

The first version uses an internal random number generator, and the second uses a Random Number Generator, a special kind of function object, that is explicitly passed as an argument.

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h. This function is an SGI extension; it is not part of the C++ standard.

Requirements on types

For the first version:
  • InputIterator is a model of Input Iterator
  • RandomAccessIterator is a model of Random Access Iterator
  • RandomAccessIterator is mutable.
  • InputIterator's value type is convertible to RandomAccessIterator's value type.
For the second version:
  • InputIterator is a model of Input Iterator
  • RandomAccessIterator is a model of Random Access Iterator
  • RandomAccessIterator is mutable.
  • RandomNumberGenerator is a model of Random Number Generator
  • InputIterator's value type is convertible to RandomAccessIterator's value type.
  • RandomAccessIterator's distance type is convertible to RandomNumberGenerator's argument type.

Preconditions

  • [first, last) is a valid range.
  • [ofirst, olast) is a valid range.
  • [first, last) and [ofirst, olast) do not overlap.
  • last - first is less than rand's maximum value.

Complexity

Linear in last - first. At most last - first elements are copied from the input range to the output range.

Example

int main()
{
  const int N = 10;
  const int n = 4;
  int A[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
  int B[n];

  random_sample(A, A+N, B, B+n);
  copy(B, B + n, ostream_iterator<int>(cout, " "));
  // The printed value might be 1 6 3 5,
  //  or any of 5039 other possibilities.
}

Notes

[1] This is "Algorithm R" from section 3.4.2 of Knuth (D. E. Knuth, The Art of Computer Programming. Volume 2: Seminumerical Algorithms, second edition. Addison-Wesley, 1981). Knuth credits Alan Waterman. Note that there are N! / n! / (N - n)! ways of selecting a sample of n elements from a range of N elements. Random_sample yields uniformly distributed results; that is, the probability of selecting any particular element is n / N, and the probability of any particular sampling (not considering order of elements) is n! * (N - n)! / N!.

[2] If preservation of the relative ordering within the input range is important for your application, you should use random_sample_n instead. The main restriction of random_sample_n is that the input range must consist of Forward Iterators, rather than Input Iterators.

See also

random_shuffle, random_sample_n, Random Number Generator


random_sample_n

Category: algorithms | Component type: function

Prototype

Random_sample_n is an overloaded name; there are actually two random_sample_n functions.
template <class ForwardIterator, class OutputIterator, class Distance>
OutputIterator random_sample_n(ForwardIterator first, ForwardIterator last,
                               OutputIterator out, Distance n)

template <class ForwardIterator, class OutputIterator, class Distance,
          class RandomNumberGenerator>
OutputIterator random_sample_n(ForwardIterator first, ForwardIterator last,
                               OutputIterator out, Distance n,
                               RandomNumberGenerator& rand)

Description

Random_sample_n randomly copies a sample of the elements from the range [first, last) into the range [out, out + n). Each element in the input range appears at most once in the output range, and samples are chosen with uniform probability. [1] Elements in the output range appear in the same relative order as their relative order within the input range. [2]

Random_sample copies m elements from [first, last) to [out, out + m), where m is min(last - first, n). The return value is out + m.

The first version uses an internal random number generator, and the second uses a Random Number Generator, a special kind of function object, that is explicitly passed as an argument.

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h. This function is an SGI extension; it is not part of the C++ standard.

Requirements on types

For the first version:
  • ForwardIterator is a model of Forward Iterator
  • OutputIterator is a model of Output Iterator
  • ForwardIterator's value type is convertible to a type in OutputIterator's set of value types.
  • Distance is an integral type that is large enough to represent the value last - first.
For the second version:
  • ForwardIterator is a model of Forward Iterator
  • OutputIterator is a model of Output Iterator
  • RandomNumberGenerator is a model of Random Number Generator
  • Distance is an integral type that is large enough to represent the value last - first.
  • ForwardIterator's value type is convertible to a type in OutputIterator's set of value types.
  • Distance is convertible to RandomNumberGenerator's argument type.

Preconditions

  • [first, last) is a valid range.
  • n is nonnegative.
  • [first, last) and [out, out + n) do not overlap.
  • There is enough space to hold all of the elements being copied. More formally, the requirement is that [out, out + min(n, last - first)) is a valid range.
  • last - first is less than rand's maximum value.

Complexity

Linear in last - first. At most last - first elements from the input range are examined, and exactly min(n, last - first) elements are copied to the output range.

Example

int main()
{
  const int N = 10;
  int A[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

  random_sample_n(A, A+N, ostream_iterator<int>(cout, " "), 4);
  // The printed value might be 3 5 6 10,
  //  or any of 209 other possibilities.
}

Notes

[1] This is "Algorithm S" from section 3.4.2 of Knuth (D. E. Knuth, The Art of Computer Programming. Volume 2: Seminumerical Algorithms, second edition. Addison-Wesley, 1981). Knuth credits C. T. Fan, M. E. Muller, and I. Rezucha (1962) and T. G. Jones (1962). Note that there are N! / n! / (N - n)! ways of selecting a sample of n elements from a range of N elements. Random_sample_n yields uniformly distributed results; that is, the probability of selecting any particular element is n / N, and the probability of any particular sampling is n! * (N - n)! / N!.

[2] In contrast, the random_sample algorithm does not preserve relative ordering within the input range. The other major distinction between the two algorithms is that random_sample_n requires its input range to be Forward Iterators and only requires its output range to be Output Iterators, while random_sample only requires its input range to be Input Iterators and requires its output range to be Random Access Iterators.

See also

random_shuffle, random_sample, Random Number Generator


random_shuffle

Category: algorithms | Component type: function

Prototype

Random_shuffle is an overloaded name; there are actually two random_shuffle functions.
template <class RandomAccessIterator>
void random_shuffle(RandomAccessIterator first, RandomAccessIterator last);

template <class RandomAccessIterator, class RandomNumberGenerator>
void random_shuffle(RandomAccessIterator first, RandomAccessIterator last,
                    RandomNumberGenerator& rand)

Description

Random_shuffle randomly rearranges the elements in the range [first, last): that is, it randomly picks one of the N! possible orderings, where N is last - first. [1] There are two different versions of random_shuffle. The first version uses an internal random number generator, and the second uses a Random Number Generator, a special kind of function object, that is explicitly passed as an argument.

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

For the first version:
  • RandomAccessIterator is a model of Random Access Iterator
For the second version:
  • RandomAccessIterator is a model of Random Access Iterator
  • RandomNumberGenerator is a model of Random Number Generator
  • RandomAccessIterator's distance type is convertible to RandomNumberGenerator's argument type.

Preconditions

  • [first, last) is a valid range.
  • last - first is less than rand's maximum value.

Complexity

Linear in last - first. If last != first, exactly (last - first) - 1 swaps are performed.

Example

const int N = 8;
int A[] = {1, 2, 3, 4, 5, 6, 7, 8};
random_shuffle(A, A + N);
copy(A, A + N, ostream_iterator<int>(cout, " "));
// The printed result might be 7 1 6 3 2 5 4 8,
//  or any of 40,319 other possibilities.

Notes

[1] This algorithm is described in section 3.4.2 of Knuth (D. E. Knuth, The Art of Computer Programming. Volume 2: Seminumerical Algorithms, second edition. Addison-Wesley, 1981). Knuth credits Moses and Oakford (1963) and Durstenfeld (1964). Note that there are N! ways of arranging a sequence of N elements. Random_shuffle yields uniformly distributed results; that is, the probability of any particular ordering is 1/N!. The reason this comment is important is that there are a number of algorithms that seem at first sight to implement random shuffling of a sequence, but that do not in fact produce a uniform distribution over the N! possible orderings. That is, it's easy to get random shuffle wrong.

See also

random_sample, random_sample_n, next_permutation, prev_permutation, Random Number Generator


raw_storage_iterator<ForwardIterator, T>

Categories: allocators, iterators, adaptors | Component type: type

Description

In C++, the operator new allocates memory for an object and then creates an object at that location by calling a constructor. Occasionally, however, it is useful to separate those two operations. [1] If i is an iterator that points to a region of uninitialized memory, then you can use construct to create an object in the location pointed to by i. Raw_storage_iterator is an adaptor that makes this procedure more convenient. If r is a raw_storage_iterator, then it has some underlying iterator i. The expression *r = x is equivalent to construct(&*i, x).

Example

class Int {
public:
  Int(int x) : val(x) {}
  int get() { return val; }
private:
  int val;
};

int main()
{
  int A1[] = {1, 2, 3, 4, 5, 6, 7};
  const int N = sizeof(A1) / sizeof(int);

  Int* A2 = (Int*) malloc(N * sizeof(Int));
  transform(A1, A1 + N,
            raw_storage_iterator<Int*, int>(A2),
            negate<int>());
}

Definition

Defined in the standard header memory, and in the nonstandard backward-compatibility header iterator.h.

Template parameters

Parameter | Description | Default
OutputIterator | The type of the raw_storage_iterator's underlying iterator. |
T | The type that will be used as the argument to the constructor. |

Model of

Output Iterator

Type requirements

  • ForwardIterator is a model of Forward Iterator
  • ForwardIterator's value type has a constructor that takes a single argument of type T.

Public base classes

None.

Members

Member | Where defined | Description
raw_storage_iterator(ForwardIterator x) | raw_storage_iterator | See below.
raw_storage_iterator(const raw_storage_iterator&) | trivial iterator | The copy constructor
raw_storage_iterator& operator=(const raw_storage_iterator&) | trivial iterator | The assignment operator
raw_storage_iterator& operator*() | Output Iterator | Used to implement the output iterator expression *i = x. [2]
raw_storage_iterator& operator=(const Sequence::value_type&) | Output Iterator | Used to implement the output iterator expression *i = x. [2]
raw_storage_iterator& operator++() | Output Iterator | Preincrement.
raw_storage_iterator& operator++(int) | Output Iterator | Postincrement.
output_iterator_tag iterator_category(const raw_storage_iterator&) | iterator tags | Returns the iterator's category. This is a global function, not a member.

New members

These members are not defined in the Output Iterator requirements, but are specific to raw_storage_iterator.
Function | Description
raw_storage_iterator(ForwardIterator i) | Creates a raw_storage_iterator whose underlying iterator is i.
raw_storage_iterator& operator=(const T& val) | Constructs an object of ForwardIterator's value type at the location pointed to by the iterator, using val as the constructor's argument.

Notes

[1] In particular, this sort of low-level memory management is used in the implementation of some container classes.

[2] Note how assignment through a raw_storage_iterator is implemented. In general, unary operator* must be defined so that it returns a proxy object, where the proxy object defines operator= to perform the insert operation. In this case, for the sake of simplicity, the proxy object is the raw_storage_iterator itself. That is, *i returns i, and *i = t is equivalent to i = t. You should not, however, rely on this behavior. It is an implementation detail, and it is not guaranteed to remain the same in future versions.

See also

Allocators, construct, destroy, uninitialized_copy uninitialized_fill, uninitialized_fill_n,


remove

Category: algorithms | Component type: function

Prototype

template <class ForwardIterator, class T>
ForwardIterator remove(ForwardIterator first, ForwardIterator last,
                       const T& value);

Description

Remove removes from the range [first, last) all elements that are equal to value. That is, remove returns an iterator new_last such that the range [first, new_last) contains no elements equal to value. [1] The iterators in the range [new_last, last) are all still dereferenceable, but the elements that they point to are unspecified. Remove is stable, meaning that the relative order of elements that are not equal to value is unchanged.

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

  • ForwardIterator is a model of Forward Iterator.
  • ForwardIterator is mutable.
  • T is a model of Equality Comparable.
  • Objects of type T can be compared for equality with objects of ForwardIterator's value type.

Preconditions

  • [first, last) is a valid range.

Complexity

Linear. Remove performs exactly last - first comparisons for equality.

Example

vector<int> V;
V.push_back(3);
V.push_back(1);
V.push_back(4);
V.push_back(1);
V.push_back(5);
V.push_back(9);

copy(V.begin(), V.end(), ostream_iterator<int>(cout, " "));
    // The output is "3 1 4 1 5 9".

vector<int>::iterator new_end = remove(V.begin(), V.end(), 1);
copy(V.begin(), new_end, ostream_iterator<int>(cout, " "));
    // The output is "3 4 5 9".

Notes

[1] The meaning of "removal" is somewhat subtle. Remove does not destroy any iterators, and does not change the distance between first and last. (There's no way that it could do anything of the sort.) So, for example, if V is a vector, remove(V.begin(), V.end(), 0) does not change V.size(): V will contain just as many elements as it did before. Remove returns an iterator that points to the end of the resulting range after elements have been removed from it; it follows that the elements after that iterator are of no interest, and may be discarded. If you are removing elements from a Sequence, you may simply erase them. That is, a reasonable way of removing elements from a Sequence is S.erase(remove(S.begin(), S.end(), x), S.end()).

See also

remove_if, remove_copy, remove_copy_if, unique, unique_copy.


remove_copy

Category: algorithms | Component type: function

Prototype

template <class InputIterator, class OutputIterator, class T>
OutputIterator remove_copy(InputIterator first, InputIterator last,
                           OutputIterator result, const T& value);

Description

Remove_copy copies elements that are not equal to value from the range [first, last) to a range beginning at result. The return value is the end of the resulting range. This operation is stable, meaning that the relative order of the elements that are copied is the same as in the range [first, last).

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

  • InputIterator is a model of Input Iterator.
  • OutputIterator is a model of Output Iterator.
  • InputIterator's value type is convertible to a type in OutputIterator's set of value types.
  • T is a model of Equality Comparable.
  • Objects of type T can be compared for equality with objects of InputIterator's value type.

Preconditions

  • [first, last) is a valid range.
  • There is enough space in the output range to store the copied values. That is, if there are n elements in [first, last) that are not equal to value, then [result, result+n) is a valid range.
  • result is not an iterator in the range [first, last).

Complexity

Linear. Exactly last - first comparisons for equality, and at most last - first assignments.

Example

Print all nonzero elements of a vector on the standard output.
vector<int> V;
V.push_back(-2);
V.push_back(0);
V.push_back(-1);
V.push_back(0);
V.push_back(1);
V.push_back(2);

remove_copy(V.begin(), V.end(),
            ostream_iterator<int>(cout, "\n"),
            0);

Notes

See also

copy, remove, remove_if, remove_copy_if, unique, unique_copy.


remove_copy_if

Category: algorithms | Component type: function

Prototype

template <class InputIterator, class OutputIterator, class Predicate>
OutputIterator remove_copy_if(InputIterator first, InputIterator last,
                              OutputIterator result, Predicate pred);

Description

Remove_copy_if copies elements from the range [first, last) to a range beginning at result, except that elements for which pred is true are not copied. The return value is the end of the resulting range. This operation is stable, meaning that the relative order of the elements that are copied is the same as in the range [first, last).

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

  • InputIterator is a model of Input Iterator.
  • OutputIterator is a model of Output Iterator.
  • InputIterator's value type is convertible to a type in OutputIterator's set of value types.
  • Predicate is a model of Predicate.
  • InputIterator's value type is convertible to Predicate's argument type.

Preconditions

  • [first, last) is a valid range.
  • There is enough space in the output range to store the copied values. That is, if there are n elements in [first, last) that do not satisfy pred, then [result, result+n) is a valid range.
  • result is not an iterator in the range [first, last).

Complexity

Linear. Exactly last - first applications of pred, and at most last - first assignments.

Example

Fill a vector with the nonnegative elements of another vector.
vector<int> V1;
V.push_back(-2);
V.push_back(0);
V.push_back(-1);
V.push_back(0);
V.push_back(1);
V.push_back(2);

vector<int> V2;
remove_copy_if(V1.begin(), V1.end(),
               back_inserter(V2),
               bind2nd(less<int>(), 0));

Notes

See also

copy, remove, remove_if, remove_copy, unique, unique_copy.


remove_if

Category: algorithms | Component type: function

Prototype

template <class ForwardIterator, class Predicate>
ForwardIterator remove_if(ForwardIterator first, ForwardIterator last,
                          Predicate pred);

Description

Remove_if removes from the range [first, last) every element x such that pred(x) is true. That is, remove_if returns an iterator new_last such that the range [first, new_last) contains no elements for which pred is true. [1] The iterators in the range [new_last, last) are all still dereferenceable, but the elements that they point to are unspecified. Remove_if is stable, meaning that the relative order of elements that are not removed is unchanged.

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

  • ForwardIterator is a model of Forward Iterator.
  • ForwardIterator is mutable.
  • Predicate is a model of Predicate.
  • ForwardIterator's value type is convertible to Predicate's argument type.

Preconditions

  • [first, last) is a valid range.

Complexity

Linear. Remove_if performs exactly last - first applications of pred.

Example

Remove all even numbers from a vector.
vector<int> V;
V.push_back(1);
V.push_back(4);
V.push_back(2);
V.push_back(8);
V.push_back(5);
V.push_back(7);

copy(V.begin(), V.end(), ostream_iterator<int>(cout, " "));
    // The output is "1 4 2 8 5 7"

vector<int>::iterator new_end =
        remove_if(V.begin(), V.end(),
                  compose1(bind2nd(equal_to<int>(), 0),
                           bind2nd(modulus<int>(), 2)));
V.erase(new_end, V.end()); [1]

copy(V.begin(), V.end(), ostream_iterator<int>(cout, " "));
    // The output is "1 5 7".

Notes

[1] The meaning of "removal" is somewhat subtle. Remove_if does not destroy any iterators, and does not change the distance between first and last. (There's no way that it could do anything of the sort.) So, for example, if V is a vector, remove_if(V.begin(), V.end(), pred) does not change V.size(): V will contain just as many elements as it did before. Remove_if returns an iterator that points to the end of the resulting range after elements have been removed from it; it follows that the elements after that iterator are of no interest, and may be discarded. If you are removing elements from a Sequence, you may simply erase them. That is, a reasonable way of removing elements from a Sequence is S.erase(remove_if(S.begin(), S.end(), pred), S.end()).

See also

remove, remove_copy, remove_copy_if, unique, unique_copy.


replace

Category: algorithms | Component type: function

Prototype

template <class ForwardIterator, class T>
void replace(ForwardIterator first, ForwardIterator last, const T& old_value,
             const T& new_value)

Description

Replace replaces every element in the range [first, last) equal to old_value with new_value. That is: for every iterator i, if *i == old_value then it performs the assignment *i = new_value.

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

  • ForwardIterator is a model of Forward Iterator.
  • ForwardIterator is mutable.
  • T is convertible to ForwardIterator's value type.
  • T is Assignable.
  • T is EqualityComparable, and may be compared for equality with objects of ForwardIterator's value type.

Preconditions

  • [first, last) is a valid range.

Complexity

Linear. Replace performs exactly last - first comparisons for equality, and at most last - first assignments.

Example

vector<int> V;
V.push_back(1);
V.push_back(2);
V.push_back(3);
V.push_back(1);

replace(V.begin(), V.end(), 1, 99);
assert(V[0] == 99 && V[3] == 99);

Notes

See also

replace_if, replace_copy, replace_copy_if


replace_copy

Category: algorithms | Component type: function

Prototype

template <class InputIterator, class OutputIterator, class T>
OutputIterator replace_copy(InputIterator first, InputIterator last,
                            OutputIterator result, const T& old_value,
                            const T& new_value);

Description

Replace_copy copies elements from the range [first, last) to the range [result, result + (last-first)), except that any element equal to old_value is not copied; new_value is copied instead. More precisely, for every integer n such that 0 <= n < last-first, replace_copy performs the assignment *(result+n) = new_value if *(first+n) == old_value, and *(result+n) = *(first+n) otherwise.

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

  • InputIterator is a model of Input Iterator.
  • OutputIterator is a model of Output Iterator.
  • T is EqualityComparable, and may be compared for equality with objects of InputIterator's value type.
  • T is Assignable.
  • T is convertible to a type in OutputIterator's set of value types.

Preconditions

  • [first, last) is a valid range.
  • There is enough space in the output range to store the copied values. That is, [result, result + (last-first)) is a valid range.
  • result is not an iterator within the range [first, last).

Complexity

Linear. Replace_copy performs exactly last - first comparisons for equality and exactly last - first assignments.

Example

vector<int> V1;
V1.push_back(1);
V1.push_back(2);
V1.push_back(3);
V1.push_back(1);

vector<int> V2(4);

replace_copy(V1.begin(), V1.end(), V2.begin(), 1, 99);
assert(V[0] == 99 && V[1] == 2 && V[2] == 3 && V[3] == 99);

Notes

See also

copy, replace, replace_if, replace_copy_if


replace_copy_if

Category: algorithms | Component type: function

Prototype

template <class InputIterator, class OutputIterator, class Predicate, class T>
OutputIterator replace_copy_if(InputIterator first, InputIterator last,
                               OutputIterator result, Predicate pred,
                               const T& new_value)

Description

Replace_copy_if copies elements from the range [first, last) to the range [result, result + (last-first)), except that any element for which pred is true is not copied; new_value is copied instead. More precisely, for every integer n such that 0 <= n < last-first, replace_copy_if performs the assignment *(result+n) = new_value if pred(*(first+n)), and *(result+n) = *(first+n) otherwise.

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

  • InputIterator is a model of Input Iterator.
  • OutputIterator is a model of Output Iterator.
  • Predicate is a model of Predicate.
  • T is convertible to Predicate's argument type.
  • T is Assignable.
  • T is convertible to a type in OutputIterator's set of value types.

Preconditions

  • [first, last) is a valid range.
  • There is enough space in the output range to store the copied values. That is, [result, result + (last-first)) is a valid range.
  • result is not an iterator within the range [first, last).

Complexity

Linear. Replace_copy performs exactly last - first applications of pred and exactly last - first assignments.

Example

Copy elements from one vector to another, replacing all negative numbers with 0.
vector<int> V1;
V1.push_back(1);
V1.push_back(-1);
V1.push_back(-5);
V1.push_back(2);

vector<int> V2(4);

replace_copy_if(V1.begin(), V1.end(), V2.begin(),
                bind2nd(less<int>(), 0),
                0);
assert(V[0] == 1 && V[1] == 0 && V[2] == 0 && V[3] == 2);

Notes

See also

copy, replace, replace_if, replace_copy


replace_if

Category: algorithms | Component type: function

Prototype

template <class ForwardIterator, class Predicate, class T>
void replace_if(ForwardIterator first, ForwardIterator last, Predicate pred
                const T& new_value)

Description

Replace_if replaces every element in the range [first, last) for which pred returns true with new_value. That is: for every iterator i, if pred(*i) is true then it performs the assignment *i = new_value.

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

  • ForwardIterator is a model of Forward Iterator.
  • ForwardIterator is mutable.
  • Predicate is a model of Predicate.
  • ForwardIterator's value type is convertible to Predicate's argument type.
  • T is convertible to Forward Iterator's value type.
  • T is Assignable.

Preconditions

  • [first, last) is a valid range.

Complexity

Linear. Replace_if performs exactly last - first applications of pred, and at most last - first assignments.

Example

Replace every negative number with 0.
vector<int> V;
V.push_back(1);
V.push_back(-3);
V.push_back(2);
V.push_back(-1);

replace_if(V.begin(), V.end(), bind2nd(less<int>(), 0), -1);
assert(V[1] == 0 && V[3] == 0);

Notes

See also

replace, replace_copy, replace_copy_if


return_temporary_buffer

Category: allocators | Component type: function

Prototype

template <class T> void return_temporary_buffer(T* p);

Description

Return_temporary_buffer is used to deallocate memory that was allocated using get_temporary_buffer. [1]

Note: get_temporary_buffer and return_temporary_buffer are only provided for backward compatibility. If you are writing new code, you should instead use the temporary_buffer class.

Definition

Defined in the standard header memory, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

Preconditions

The argument p is a pointer to a block of memory that was allocated using get_temporary_buffer(ptrdiff_t, T*).

Complexity

Example

int main()
{
  pair<int*, ptrdiff_t> P = get_temporary_buffer(10000, (int*) 0);
  int* buf = P.first;
  ptrdiff_t N = P.second;
  uninitialized_fill_n(buf, N, 42);
  int* result = find_if(buf, buf + N, bind2nd(not_equal_to<int>(), 42));
  assert(result == buf + N);
  return_temporary_buffer(buf);
}

Notes

[1] As is always true, memory that was allocated using a particular allocation function must be deallocated using the corresponding deallocation function. Memory obtained using get_temporary_buffer must be deallocated using return_temporary_buffer, rather than using free or ::operator delete.

See also

temporary_buffer, get_temporary_buffer, Allocators


reverse

Category: algorithms | Component type: function

Prototype

template <class BidirectionalIterator>
void reverse(BidirectionalIterator first, BidirectionalIterator last);

Description

Reverse reverses a range. That is: for every i such that 0 <= i <= (last - first) / 2), it exchanges *(first + i) and *(last - (i + 1)).

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

  • BidirectionalIterator is a model of Bidirectional Iterator.
  • BidirectionalIterator is mutable.

Preconditions

  • [first, last) is a valid range.

Complexity

Linear: reverse(first, last) makes (last - first) / 2 calls to swap.

Example

vector<int> V;
V.push_back(0);
V.push_back(1);
V.push_back(2);
copy(V.begin(), V.end(), ostream_iterator<int>(cout, " "));
                // Output: 0 1 2
reverse(V.begin(), V.end());
copy(V.begin(), V.end(), ostream_iterator<int>(cout, " "));
                // Output: 2 1 0

Notes

See also

reverse_copy


reverse_bidirectional_iterator<BidirectionalIterator, T, Reference, Distance>

Categories: iterators, adaptors | Component type: type

Description

Reverse_bidirectional_iterator is an iterator adaptor that enables backwards traversal of a range. Operator++ applied to an object of class reverse_bidirectional_iterator<BidirectionalIterator> means the same thing as operator-- applied to an object of class BidirectionalIterator. There are two different reverse iterator adaptors: the class reverse_bidirectional_iterator has a template argument that is a Bidirectional Iterator, and the class reverse_iterator has a template argument that is a Random Access Iterator. [1]

Example

template <class T>
void forw(const list<T>& L)
{
   list<T>::iterator first = L.begin();
   list<T>::iterator last = L.end();
   while (first != last)
      cout << *first++ << endl;
}

template <class T>
void rev(const list<T>& L)
{
   typedef reverse_bidirectional_iterator<list<T>::iterator,
                                          T,
                                          list<T>::reference_type,
                                          list<T>::difference_type>
           reverse_iterator; [2]
   reverse_iterator rfirst(L.end());
   reverse_iterator rlast(L.begin());

   while (rfirst != rlast)
      cout << *rfirst++ << endl;
}

In the function forw, the elements are printed in the order *first, *(first+1), ..., *(last-1). In the function rev, they are printed in the order *(last - 1), *(last-2), ..., *first. [3]

Definition

Defined in the standard header iterator, and in the nonstandard backward-compatibility header iterator.h. This class is no longer part of the C++ standard, but it was present in early drafts, and it is retained in this implementation for backward compatibility.

Template parameters

Parameter | Description | Default
BidirectionalIterator | The base iterator class. Incrementing an object of class reverse_bidirectional_iterator<BidirectionalIterator> corresponds to decrementing an object of class BidirectionalIterator. |
T | The reverse iterator's value type. This should always be the same as the base iterator's value type. |
Reference | The reverse iterator's reference type. This should always be the same as the base iterator's reference type. | T&
Distance | The reverse iterator's distance type. This should always be the same as the base iterator's distance type. | ptrdiff_t

Model of

Bidirectional Iterator.

Type requirements

The base iterator type (that is, the template parameter BidirectionalIterator) must be a Bidirectional Iterator. The reverse_bidirectional_iterator's value type, reference type, and distance type (that is, the template parameters T, Reference, and Distance, respectively) must be the same as the base iterator's value type, reference type, and distance type.

Public base classes

None.

Members

Member | Where defined | Description
self | reverse_bidirectional_iterator | See below
reverse_bidirectional_iterator() | Trivial Iterator | The default constructor
reverse_bidirectional_iterator(const reverse_bidirectional_iterator& x) | Trivial Iterator | The copy constructor
reverse_bidirectional_iterator& operator=(const reverse_bidirectional_iterator& x) | Trivial Iterator | The assignment operator
reverse_bidirectional_iterator(BidirectionalIterator x) | reverse_bidirectional_iterator | See below.
BidirectionalIterator base() | reverse_bidirectional_iterator | See below.
Reference operator*() const | Trivial Iterator | The dereference operator
reverse_bidirectional_iterator& operator++() | Forward Iterator | Preincrement
reverse_bidirectional_iterator operator++(int) | Forward Iterator | Postincrement
reverse_bidirectional_iterator& operator--() | Bidirectional Iterator | Predecrement
reverse_bidirectional_iterator operator--(int) | Bidirectional Iterator | Postdecrement
bool operator==(const reverse_bidirectional_iterator&, const reverse_bidirectional_iterator&) | Trivial Iterator | Compares two iterators for equality. This is a global function, not a member function.
bidirectional_iterator_tag iterator_category(const reverse_bidirectional_iterator&) | Iterator tags | Returns the iterator's category. This is a global function, not a member function.
T* value_type(const reverse_bidirectional_iterator&) | Iterator tags | Returns the iterator's value type. This is a global function, not a member function.
Distance* distance_type(const reverse_bidirectional_iterator&) | Iterator tags | Returns the iterator's distance type. This is a global function, not a member function.

New members

These members are not defined in the Bidirectional Iterator requirements, but are specific to reverse_bidirectional_iterator.
Member | Description
self | A typedef for reverse_bidirectional_iterator<BidirectionalIterator, T, Reference, Distance>.
BidirectionalIterator base() | Returns the current value of the reverse_bidirectional_iterator's base iterator. If ri is a reverse iterator and i is any iterator, the two fundamental identities of reverse iterators can be written as reverse_bidirectional_iterator(i).base() == i and &*ri == &*(ri.base() - 1).
reverse_bidirectional_iterator(BidirectionalIterator i) | Constructs a reverse_bidirectional_iterator whose base iterator is i.

Notes

[1] There isn't really any good reason to have two separate classes: this separation is purely because of a technical limitation in some of today's C++ compilers. If the two classes were combined into one, then there would be no way to declare the return types of the iterator tag functions iterator_category, distance_type and value_type correctly. The iterator traits class solves this problem: it addresses the same issues as the iterator tag functions, but in a cleaner and more flexible manner. Iterator traits, however, rely on partial specialization, and many C++ compilers do not yet implement partial specialization. Once compilers that support partial specialization become more common, these two different reverse iterator classes will be combined into a single class.

[2] The declarations for rfirst and rlast are written in this clumsy form simply as an illustration of how to declare a reverse_bidirectional_iterator. List is a Reversible Container, so it provides a typedef for the appropriate instantiation of reverse_bidirectional_iterator. The usual way of declaring these variables is much simpler:

    list<T>::reverse_bidirectional_iterator rfirst = rbegin();
    list<T>::reverse_bidirectional_iterator rlast = rend();

[3] Note the implications of this remark. The variable rfirst is initialized as reverse_bidirectional_iterator<...> rfirst(V.end());. The value obtained when it is dereferenced, however, is *(V.end() - 1). This is a general property: the fundamental identity of reverse iterators is &*(reverse_bidirectional_iterator(i)) == &*(i - 1). This code sample shows why this identity is important: if [f, l) is a valid range, then it allows [reverse_bidirectional_iterator(l), reverse_bidirectional_iterator(f)) to be a valid range as well. Note that the iterator l is not part of the range, but it is required to be dereferenceable or past-the-end. There is no requirement that any such iterator precedes f.

See also

Reversible Container, reverse_iterator, Bidirectional Iterator, iterator tags, Iterator overview


reverse_iterator<RandomAccessIterator, T, Reference, Distance>

Categories: iterators, adaptors | Component type: type

Description

Reverse_iterator is an iterator adaptor that enables backwards traversal of a range. Operator++ applied to an object of class reverse_iterator<RandomAccessIterator> means the same thing as operator-- applied to an object of class RandomAccessIterator. There are two different reverse iterator adaptors: the class reverse_iterator has a template argument that is a Random Access Iterator, and the class reverse_bidirectional_iterator has a template argument that is a Bidirectional Iterator. [1]

Example

template <class T>
void forw(const vector<T>& V)
{
   vector<T>::iterator first = V.begin();
   vector<T>::iterator last = V.end();
   while (first != last)
      cout << *first++ << endl;
}

template <class T>
void rev(const vector<T>& V)
{
   typedef reverse_iterator<vector<T>::iterator,
                            T,
                            vector<T>::reference_type,
                            vector<T>::difference_type>
           reverse_iterator; [2]
   reverse_iterator rfirst(V.end());
   reverse_iterator rlast(V.begin());

   while (rfirst != rlast)
      cout << *rfirst++ << endl;
}

In the function forw, the elements are printed in the order *first, *(first+1), ..., *(last-1). In the function rev, they are printed in the order *(last - 1), *(last-2), ..., *first. [3]

Definition

Defined in the standard header iterator, and in the nonstandard backward-compatibility header iterator.h.

Template parameters

Parameter | Description | Default
RandomAccessIterator | The base iterator class. Incrementing an object of class reverse_iterator<Iterator> corresponds to decrementing an object of class Iterator. |
T | The reverse iterator's value type. This should always be the same as the base iterator's value type. |
Reference | The reverse iterator's reference type. This should always be the same as the base iterator's reference type. | T&
Distance | The reverse iterator's distance type. This should always be the same as the base iterator's distance type. | ptrdiff_t

Model of

Random Access Iterator

Type requirements

The base iterator type (that is, the template parameter RandomAccessIterator) must be a Random Access Iterator. The reverse_iterator's value type, reference type, and distance type (that is, the template parameters T, Reference, and Distance, respectively) must be the same as the base iterator's value type, reference type, and distance type.

Public base classes

None.

Members

Member | Where defined | Description
self | reverse_iterator | See below
reverse_iterator() | Trivial Iterator | The default constructor
reverse_iterator(const reverse_iterator& x) | Trivial Iterator | The copy constructor
reverse_iterator& operator=(const reverse_iterator& x) | Trivial Iterator | The assignment operator
reverse_iterator(RandomAccessIterator x) | reverse_iterator | See below.
RandomAccessIterator base() | reverse_iterator | See below.
Reference operator*() const | Trivial Iterator | The dereference operator
reverse_iterator& operator++() | Forward Iterator | Preincrement
reverse_iterator operator++(int) | Forward Iterator | Postincrement
reverse_iterator& operator--() | Bidirectional Iterator | Predecrement
reverse_iterator operator--(int) | Bidirectional Iterator | Postdecrement
reverse_iterator operator+(Distance) | Random Access Iterator | Iterator addition
reverse_iterator& operator+=(Distance) | Random Access Iterator | Iterator addition
reverse_iterator operator-(Distance) | Random Access Iterator | Iterator subtraction
reverse_iterator& operator-=(Distance) | Random Access Iterator | Iterator subtraction
Reference operator[](Distance) | Random Access Iterator | Random access to an element.
reverse_iterator operator+(Distance, reverse_iterator) | Random Access Iterator | Iterator addition. This is a global function, not a member function.
Distance operator-(const reverse_iterator&, const reverse_iterator&) | Random Access Iterator | Finds the distance between two iterators. This is a global function, not a member function.
bool operator==(const reverse_iterator&, const reverse_iterator&) | Trivial Iterator | Compares two iterators for equality. This is a global function, not a member function.
bool operator<(const reverse_iterator&, const reverse_iterator&) | Random Access Iterator | Determines whether the first argument precedes the second. This is a global function, not a member function.
random_access_iterator_tag iterator_category(const reverse_iterator&) | Iterator tags | Returns the iterator's category. This is a global function, not a member function.
T* value_type(const reverse_iterator&) | Iterator tags | Returns the iterator's value type. This is a global function, not a member function.
Distance* distance_type(const reverse_iterator&) | Iterator tags | Returns the iterator's distance type. This is a global function, not a member function.

New members

These members are not defined in the Random Access Iterator requirements, but are specific to reverse_iterator.
Member | Description
self | A typedef for reverse_iterator<RandomAccessIterator, T, Reference, Distance>.
RandomAccessIterator base() | Returns the current value of the reverse_iterator's base iterator. If ri is a reverse iterator and i is any iterator, the two fundamental identities of reverse iterators can be written as reverse_iterator(i).base() == i and &*ri == &*(ri.base() - 1).
reverse_iterator(RandomAccessIterator i) | Constructs a reverse_iterator whose base iterator is i.

Notes

[1] There isn't really any good reason to have two separate classes: this separation is purely because of a technical limitation in some of today's C++ compilers. If the two classes were combined into one, then there would be no way to declare the return types of the iterator tag functions iterator_category, distance_type and value_type correctly. The iterator traits class solves this problem: it addresses the same issues as the iterator tag functions, but in a cleaner and more flexible manner. Iterator traits, however, rely on partial specialization, and many C++ compilers do not yet implement partial specialization. Once compilers that support partial specialization become more common, these two different reverse iterator classes will be combined into a single class.

[2] The declarations for rfirst and rlast are written in this clumsy form simply as an illustration of how to declare a reverse_iterator. Vector is a Reversible Container, so it provides a typedef for the appropriate instantiation of reverse_iterator. The usual way of declaring these variables is much simpler:

    vector<T>::reverse_iterator rfirst = rbegin();
    vector<T>::reverse_iterator rlast = rend();

[3] Note the implications of this remark. The variable rfirst is initialized as reverse_iterator<...> rfirst(V.end());. The value obtained when it is dereferenced, however, is *(V.end() - 1). This is a general property: the fundamental identity of reverse iterators is &*(reverse_iterator(i)) == &*(i - 1). This code sample shows why this identity is important: if [f, l) is a valid range, then it allows [reverse_iterator(l), reverse_iterator(f)) to be a valid range as well. Note that the iterator l is not part of the range, but it is required to be dereferenceable or past-the-end. There is no requirement that any such iterator precedes f.

See also

Reversible Container, reverse_bidirectional_iterator, Random Access Iterator, iterator tags, Iterator Overview


reverse_copy

Category: algorithms | Component type: function

Prototype

template <class BidirectionalIterator, class OutputIterator>
OutputIterator reverse_copy(BidirectionalIterator first,
                            BidirectionalIterator last,
                            OutputIterator result);

Description

Reverse_copy copies elements from the range [first, last) to the range [result, result + (last - first)) such that the copy is a reverse of the original range. Specifically: for every i such that 0 <= i < (last - first), reverse_copy performs the assignment *(result + (last - first) - i) = *(first + i).

The return value is result + (last - first).

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

  • BidirectionalIterator is a model of Bidirectional Iterator.
  • OutputIterator is a model of Output Iterator.
  • The value type of BidirectionalIterator is convertible to a type in OutputIterator's set of value types.

Preconditions

  • [first, last) is a valid range.
  • There is enough space to hold all of the elements being copied. More formally, the requirement is that [result, result + (last - first)) is a valid range.
  • The ranges [first, last) and [result, result + (last - first)) do not overlap.

Complexity

Linear: exactly last - first assignments.

Example

vector<int> V;
V.push_back(0);
V.push_back(1);
V.push_back(2);
copy(V.begin(), V.end(), ostream_iterator<int>(cout, " "));
                // Output: 0 1 2
list<int> L(V.size());
reverse_copy(V.begin(), V.end(), L.begin());
copy(L.begin(), L.end(), ostream_iterator<int>(cout, " "));
                // Output: 2 1 0

Notes

See also

reverse, copy


Reversible Container

Category: containers | Component type: concept

Description

A Reversible Container is a Forward Container whose iterators are Bidirectional Iterators. It allows backwards iteration through the container.

Refinement of

Forward Container

Associated types

Two new types are introduced. In addition, the iterator type and the const iterator type must satisfy a more stringent requirement than for a Forward Container. The iterator and reverse iterator types must be Bidirectional Iterators, not merely Forward Iterators.
Reverse iterator type | X::reverse_iterator | A Reverse Iterator adaptor whose base iterator type is the container's iterator type. Incrementing an object of type reverse_iterator moves backwards through the container: the Reverse Iterator adaptor maps operator++ to operator--.
Const reverse iterator type | X::const_reverse_iterator | A Reverse Iterator adaptor whose base iterator type is the container's const iterator type. [1]

Notation

X | A type that is a model of Reversible Container
a, b | Object of type X

Definitions

Valid expressions

In addition to the expressions defined in Forward Container, the following expressions must be valid.
Name | Expression | Type requirements | Return type
Beginning of range | a.rbegin() |  | reverse_iterator if a is mutable, const_reverse_iterator otherwise [1]
End of range | a.rend() |  | reverse_iterator if a is mutable, const_reverse_iterator otherwise [1]

Expression semantics

Semantics of an expression is defined only where it is not defined in Forward Container, or where there is additional information.
Name | Expression | Precondition | Semantics | Postcondition
Beginning of reverse range | a.rbegin() |  | Equivalent to X::reverse_iterator(a.end()). | a.rbegin() is dereferenceable or past-the-end. It is past-the-end if and only if a.size() == 0.
End of reverse range | a.rend() |  | Equivalent to X::reverse_iterator(a.begin()). | a.end() is past-the-end.

Complexity guarantees

The run-time complexity of rbegin() and rend() is amortized constant time.

Invariants

Valid range | [a.rbegin(), a.rend()) is a valid range.
Equivalence of ranges | The distance from a.begin() to a.end() is the same as the distance from a.rbegin() to a.rend().

Models

  • vector
  • list
  • deque

Notes

[1] A Container's iterator type and const iterator type may be the same type: a container need not provide mutable iterators. It follows from this that the reverse iterator type and the const reverse iterator type may also be the same.

See also

The Iterator overview, Bidirectional Iterator, Sequence


rope<T, Alloc>

Category: containers | Component type: type

Description

Ropes are a scalable string implementation: they are designed for efficient operation that involve the string as a whole. Operations such as assignment, concatenation, and substring take time that is nearly independent of the length of the string. Unlike C strings, ropes are a reasonable representation for very long strings such as edit buffers or mail messages. [1]

Though ropes can be treated as Containers of characters, and are almost Sequences, this is rarely the most efficient way to accomplish a task. Replacing an individual character in a rope is slow: each character replacement essentially consists of two substring operations followed by two concatenation operations. Ropes primarily target a more functional programming style.

They differ from vector<char> or reference-counted string implementations in the following ways.

Advantages:

  • Much faster concatenation and substring operations involving long strings. Inserting a character in the middle of a 10 megabyte rope should take on the order of 10s of microseconds, even if a copy of the original is kept, e.g. as part of an edit history. In contrast, this would take on the order of a second for conventional "flat" string representation. The time required for concatenation can be viewed as constant for most applications. It is perfectly reasonable to use a rope as the representation of a file inside a text editor.
  • Potentially much better space performance. Minor modifications of a rope can share memory with the original. Ropes are allocated in small chunks, significantly reducing memory fragmentation problems introduced by large blocks.
  • Assignment is simply a (possibly reference counted) pointer assignment. Unlike reference-counted copy-on-write implementations, this remains largely true even if one of the copies is subsequently slightly modified. It is very inexpensive to checkpoint old versions of a string, e.g. in an edit history.
  • It is possible to view a function producing characters as a rope. Thus a piece of a rope may be a 100MByte file, which is read only when that section of the string is examined. Concatenating a string to the end of such a file does not involve reading the file. (Currently the implementation of this facility is incomplete.)
Disadvantages:
  • Single character replacements in a rope are expensive. A character update requires time roughly logarithmic in the length of the string. It is implemented as two substring operations followed by two concatenations.
  • A rope can be examined a character at a time through a const_iterator in amortized constant time, as for vector<char>. However this is slower than for vector<char> by a significant constant factor (roughly a factor of 5 or 10 if little processing is done on each character and the string is long). Nonconst iterators involve additional checking, and are hence a bit slower still. (We expect that eventually some common algorithms will be specialized so that this cost is not encountered. Currently only output, conversion to a C string, and the single-character find member function are treated in this way.)
  • Iterators are on the order of a dozen words in size. This means that copying them, though not tremendously expensive, is not a trivial operation. Avoid postincrementing iterators; use preincrement whenever possible. (The interface also provides primitives for indexing into a string using integer character positions. Passing positions around is clearly much cheaper, but this makes the indexing operation expensive, again roughly logarithmic in the length of the rope.)
Experience with previous implementations for other programming languages suggests that ropes are a good choice as the normal or default representation of strings in a program. It will occasionally be necessary to use some type of character array, such as vector<char>, in places that are particularly sensitive to the performance of traversals or in-place updates. But the use of ropes minimizes the number of cases in which program running times become intolerable due to unexpectedly long string inputs.

A rope is almost, but not quite, a Sequence. It supports random access const_iterators. Forward or backward traversals take constant time per operation. Nonconstant iterators are also provided. However, assignment through a nonconst iterator is an expensive operation (basically logarithmic time, but with a large constant). It should be avoided in frequently executed code.

In order to discourage accidental use of expensive operations, the begin and end member functions on ropes return const_iterator. If non-const iterators are desired, the member functions mutable_begin and mutable_end should be used.

Any modification of a rope invalidates const iterators referring to the rope. Mutable iterators refer to the same position in the same rope after an update. (This may be surprising if the iterators refers to a position after an insertion point.) They remain valid unless the iterator refers to a position that is more than one past the end of the resulting rope.

Definition

Defined in the header rope, and in the backward-compatibility header rope.h. The rope class, and the rope header, are SGI extensions; they are not part of the C++ standard.

Example

crope r(1000000, 'x');          // crope is rope<char>. wrope is rope<wchar_t>
                                // Builds a rope containing a million 'x's.
                                // Takes much less than a MB, since the
                                // different pieces are shared.
crope r2 = r + "abc" + r;       // concatenation; takes on the order of 100s
                                // of machine instructions; fast
crope r3 = r2.substr(1000000, 3);       // yields "abc"; fast.
crope r4 = r2.substr(1000000, 1000000); // also fast.
reverse(r2.mutable_begin(), r2.mutable_end());
                                // correct, but slow; may take a
                                // minute or more.

Template parameters

Parameter | Description | Default
T | The rope's value type: usually char or wchar_t. [2] |
Alloc | The rope's allocator, used for all internal memory management. | alloc

Model of

Random Access Container. Almost, but not quite, a model of Front Insertion Sequence and Back Insertion Sequence.

Type requirements

None, except for those imposed by the requirements of Random Access Container.

Public base classes

None.

Members

Member | Where defined | Description
value_type | Container | The rope's value type T, usually char or wchar_t.
difference_type | Container | A signed integral type.
size_type | Container | An unsigned integral type.
reference | Container | Reference to a rope element. [3]
const_reference | Container | Const reference to T. [3]
pointer | Container | Pointer to T. [3]
const_pointer | Container | Const pointer to T. [3]
const_reverse_iterator | Reversible Container | Const iterator used to iterate backwards through a rope.
reverse_iterator | Reversible Container | Mutable iterator used to iterate backwards through a rope.
iterator | Container | Mutable random access iterator used to iterate through a rope.
const_iterator | Container | Const random access iterator used to iterate through a rope.
rope(const charT* s) | rope. | Constructs a rope from a C string.
rope(const charT* s, size_t n) | rope. | Constructs a rope from a (not necessarily null-terminated) array of charT.
rope(const const_iterator& f, const const_iterator& l) | Sequence | Creates a rope with a copy of a range.
rope(const iterator& f, const iterator& l) | Sequence | Creates a rope with a copy of a range.
rope(const charT* f, const charT* l) | Sequence | Creates a rope with a copy of a range.
rope(charT c) | rope. | Single-character constructor.
rope() | Container | Default constructor.
rope(char_producer<charT>*, size_t, bool) | rope | See below.
rope(const rope& x) | Container | The copy constructor.
~rope() | Container | The destructor.
rope& operator=(const rope&x) | Container | The assignment operator.
void swap(rope& x) | Container | Swaps the contents of two ropes.
size_type size() const | Container | Returns the size of the rope.
size_type length() const | rope | Same as size
size_type max_size() const | Container | Size of longest rope guaranteed to be representable.
bool empty() const | Container | Equivalent to size() == 0.
const_iterator begin() const | Container | Returns an const_iterator pointing to the beginning of the rope.
const_iterator end() const | Container | Returns an const_iterator pointing to the end of the rope.
iterator mutable_begin() | rope | Returns an iterator pointing to the beginning of the rope.
iterator mutable_end() | rope | Returns an iterator pointing to the end of the rope.
const_reverse_iterator rbegin() const | Reversible Container | Returns a const_reverse_iterator pointing to the beginning of the reversed rope
const_reverse_iterator rend() const | Reversible Container | Returns a const_reverse_iterator pointing to the end of the reversed rope
iterator mutable_rbegin() | rope | Returns a reverse_iterator pointing to the beginning of the reversed rope.
iterator mutable_rend() | rope | Returns a reverse_iterator pointing to the end of the reversed rope.
charT operator[](size_type n) const | Random Access Container | Returns the n'th element.
charT at(size_type pos) const | Random Access Container | Returns the n'th element.
reference mutable_reference_at(size_type n) | rope | Returns a reference to the nth element.
int compare(const rope&) const | rope. | Three-way comparison. See below.
charT front() const | Sequence | Returns the first element.
charT back() const | Back Insertion Sequence | Returns the last element.
void push_front() | Front Insertion Sequence | Inserts a new element at the front.
void push_back(charT) | Back Insertion Sequence | Inserts a new element at the end.
void pop_front() | Front Insertion Sequence | Removes the first element.
void pop_back() | Back Insertion Sequence | Removes the last element.
iterator insert(const iterator& p, const rope& x) | rope | Inserts the contents of x before p.
iterator insert(const iterator& p, charT c) | Sequence | Inserts c before p.
iterator insert(const iterator& p) | Sequence | Inserts charT() before p.
iterator insert(const iterator& p, size_t n, charT c) | Sequence | Inserts n copies of c before p.
iterator insert(const iterator& p, const charT* s) | rope | Inserts a C string before p.
iterator insert(const iterator& p, const charT* s, size_t n) | rope | Inserts a (not necessarily null-terminated) array of charT before p.
iterator insert(const iterator& p, const charT* f, const char* l) | Sequence | Inserts the range [f, l) before p.
iterator insert(const iterator& p,
                const const_iterator& f, const const_iterator& l)
Sequence Inserts the range [f, l) before p.
iterator insert(const iterator& p,
                const iterator& f, const iterator& l)
Sequence Inserts the range [f, l) before p.
void insert(size_t i, const rope& x) | rope | Inserts the contents of x before the ith element.
void insert(size_t i, charT c) | rope | Inserts the character c before the ith element.
void insert(size_t i) | rope | Inserts the character charT() before the ith element.
void insert(size_t i, size_t n, charT c) | rope | Inserts n copies of c before the ith element.
void insert(size_t i, const charT* s) | rope | Inserts a C string before the ith element.
void insert(size_t i, const charT* s, size_t n) | rope | Inserts a (not necessarily null-terminated) array of charT before the ith element.
void insert(size_t i, const charT* f, const charT* l) | rope | Inserts the range [f, l) before the ith element.
void insert(size_t i,
            const const_iterator& f, const const_iterator& l)
rope Inserts the range [f, l) before the ith element.
void insert(size_t i,
            const iterator& f, const iterator& l)
rope Inserts the range [f, l) before the ith element.
void erase(const iterator& p) | Sequence | Erases the element pointed to by p.
void erase(const iterator& f, const iterator& l) | Sequence | Erases the range [f, l).
void erase(size_t i, size_t n) | rope | Erases n elements, starting with the ith element.
append(const charT* s) | rope | Appends a C string.
append(const charT* s, size_t) | rope | Appends a (not necessarily null-terminated) array of charT.
append(const charT* f, const charT* l) | rope | Appends a range.
append(charT c) | rope | Appends the character c.
append() | rope | Appends the character charT().
append(size_t n, charT c) | rope | Appends n copies of c.
append(const rope& x) | rope | Appends the rope x.
void replace(const iterator& f, const iterator& l, const rope&) | rope | See below.
void replace(const iterator& f, const iterator& l, charT) | rope | See below.
void replace(const iterator& f, const iterator& l, const charT* s) | rope | See below.
void replace(const iterator& f, const iterator& l,
             const charT* s, size_t n)
rope See below.
void replace(const iterator& f1, const iterator& l1,
             const charT* f2, const charT* l2)
rope See below.
void replace(const iterator& f1, const iterator& l1,
             const const_iterator& f2, const const_iterator& l2)
rope See below.
void replace(const iterator& f1, const iterator& l1,
             const iterator& f2, const iterator& l2)
rope See below.
void replace(const iterator& p, const rope& x) | rope | See below.
void replace(const iterator& p, charT c) | rope | See below.
void replace(const iterator& p, const charT* s) | rope | See below.
void replace(const iterator& p, const charT* s, size_t n) | rope | See below.
void replace(const iterator& p,
             const charT* f, const charT* l)
rope See below.
void replace(const iterator& p,
             const_iterator f, const_iterator l)
rope See below.
void replace(const iterator& p,
             iterator f, iterator l)
rope See below.
void replace(size_t i, size_t n, const rope& x) | rope | See below.
void replace(size_t i, size_t n, const charT* s, size_t n) | rope | See below.
void replace(size_t i, size_t n, charT c) | rope | See below.
void replace(size_t i, size_t n, const charT* s) | rope | See below.
void replace(size_t i, size_t n,
             const charT* f, const charT* l)
rope See below.
void replace(size_t i, size_t n,
             const const_iterator& f,
             const const_iterator& l)
rope See below.
void replace(size_t i, size_t n,
             const iterator& f,
             const iterator& l)
rope See below.
void replace(size_t i, charT c) | rope | See below.
void replace(size_t i, const rope& x) | rope | See below.
void replace(size_t i, const charT* s) | rope | See below.
void replace(size_t i, const charT* s, size_t n) | rope | See below.
void replace(size_t i, const charT* f, const charT* l) | rope | See below.
void replace(size_t i,
             const const_iterator& f, const const_iterator& l)
rope See below.
void replace(size_t i,
             const iterator& f, const iterator& l)
rope See below.
rope substr(iterator f) const | rope | See below.
rope substr(const_iterator f) const | rope | See below.
rope substr(iterator f, iterator l) const | rope | See below.
rope substr(const_iterator f, const_iterator l) const | rope | See below.
rope substr(size_t i, size_t n = 1) const | rope | See below.
void copy(charT* buf) const | rope | Copies a rope into an array of charT.
size_type copy(size_type pos, size_type n,
               charT* buf)
rope Copies a rope into an array of charT.
const charT* c_str() const | rope | See below.
void delete_c_str() | rope | See below.
rope operator+(const rope& L, const rope&R) | rope | Concatenates L and R. This is a global function, not a member function.
rope& operator+=(rope& L, const rope& R) | rope | Appends R to L. This is a global function, not a member function.
rope operator+(const rope& L, const charT* s) | rope | Concatenates L and s. This is a global function, not a member function.
rope& operator+=(rope& L, const charT* s) | rope | Appends s to L. This is a global function, not a member function.
rope operator+(const rope& L, charT c) | rope | Concatenates L and c. This is a global function, not a member function.
rope& operator+=(rope& L, charT c) | rope | Appends c to L. This is a global function, not a member function.
bool operator<(const rope&, const rope&) | Forward Container | Lexicographical comparison. This is a global function, not a member function.
bool operator==(const rope&, const rope*) | Forward Container | Tests two ropes for equality. This is a global function, not a member function.
ostream& operator<<(ostream& os, rope x) | rope | Outputs x to the stream os. This is a global function, not a member function.

New members

These members are not defined in the Random Access Container requirements, but are specific to rope:
Function | Description
rope(const charT* s) | Constructs a rope from a C string. The rope consists of the sequence of characters starting with *s up to, but not including, the first null character.
rope(const charT* s, size_t n) | Constructs a rope from an array of charT. The rope consists of the characters in the range [s, s + n). Note that this range is permitted to contain embedded null characters.
rope(charT c) | Constructs a rope consisting of the single character c.
rope(char_producer<charT>* cp, size_t n, bool destroy) | Constructs a rope of size n, whose characters are computed as needed by cp. The object *cp must be valid as long as any reference to the resulting rope, or a rope derived from it, may be used. If destroy is true, then delete cp will be executed automatically once cp is no longer needed. Typically destroy will be true unless cp is a pointer to statically allocated storage. It is rarely safe to allocate *cp on the stack.
size_type length() const | Synonym for size
iterator mutable_begin() | Returns an iterator pointing to the beginning of the rope. This member function exists because mutable rope iterators are much more expensive than constant rope iterators.
iterator mutable_end() | Returns an iterator pointing to the end of the rope. This member function exists because mutable rope iterators are much more expensive than constant rope iterators.
iterator mutable_rbegin() | Returns a reverse_iterator pointing to the beginning of the reversed rope. This member function exists because mutable rope iterators are much more expensive than constant rope iterators.
iterator mutable_rend() | Returns a reverse_iterator pointing to the end of the reversed rope. This member function exists because mutable rope iterators are much more expensive than constant rope iterators.
reference mutable_reference_at(size_type n) | Returns a reference to the nth element. This member function exists because mutable references to rope elements have fairly high overhead.
int compare(const rope& x) | Three-way comparison, much like the function strcmp from the standard C library. Returns a negative number if *this is lexicographically less than x, a positive number if *this is lexicographically greater than x, and zero if neither rope is lexicographically less than the other.
iterator insert(const iterator& p, const rope& x) | Inserts the contents of the rope x immediately before the position p.
iterator insert(const iterator& p, const charT* s) | Inserts a C string immediately before the position p. The elements that are inserted are the sequence of characters starting with *s and up to, but not including, the first null character.
iterator insert(const iterator& p, const charT* s, size_t n) | Inserts an array of charT. The elements that are inserted are the range [s, s + n). Note that this range is permitted to contain embedded null characters.
void insert(size_t i, const rope& x) | Inserts the contents of the rope x immediately before the ith element.
void insert(size_t i, size_t n, charT c) | Inserts n copies of c immediately before the ith element.
void insert(size_t i, const charT* s) | Inserts a C string immediately before the ith element. The elements that are inserted are the sequence of characters starting with *s and up to, but not including, the first null character.
void insert(size_t i, const charT* s, size_t n) | Inserts an array of charT immediately before the ith element. The elements that are inserted are the range [s, s + n). Note that this range is permitted to contain embedded null characters.
void insert(size_t i, charT c) | Inserts the character c immediately before the ith element.
void insert(size_t i) | Inserts the character charT() immediately before the ith element.
void insert(size_t i, const charT* f, const charT* l) | Inserts the range [f, l) immediately before the ith element.
void insert(size_t i,
            const const_iterator& f, const const_iterator& l)
Inserts the range [f, l) immediately before the ith element.
void insert(size_t i,
            const iterator& f, const iterator& l)
Inserts the range [f, l) immediately before the ith element.
void erase(size_t i, size_t n) | Erases n elements, starting with the ith element.
append(const charT* s) | Adds a C string to the end of the rope. The elements that are inserted are the sequence of characters starting with *s and up to, but not including, the first null character.
append(const charT* s, size_ nt) | Adds an array of charT to the end of the rope. The elements that are inserted are the range [s, s + n). Note that this range is permitted to contain embedded null characters.
append(const charT* f, const charT* l) | Adds the elements in the range [f, l) to the end of the rope.
append(charT c) | Adds the character c to the end of the rope.
append() | Adds the character charT() to the end of the rope.
append(const rope& x) | Adds the contents of the rope x to the end of *this.
append(size_t n, charT c) | Adds n copies of c to the end of *this.
void replace(const iterator& f, const iterator& l, const rope& x) | Replaces the elements in the range [f, l) with the elements in x.
void replace(const iterator& f, const iterator& l, charT c) | Replaces the elements in the range [f, l) with the single character c.
void replace(const iterator& f, const iterator& l, const charT* s) | Replaces the elements in the range [f, l) with a C string: the sequence of characters beginning with *s and up to, but not including, the first null character.
void replace(const iterator& f, const iterator& l,
             const charT* s, size_t n)
Replaces the elements in the range [f, l) with the elements in the range [s, s + n).
void replace(const iterator& f1, const iterator& l1,
             const charT* f2, const charT* l2)
Replaces the elements in the range [f1, l1) with the elements in the range [f2, l2).
void replace(const iterator& f1, const iterator& l1,
             const const_iterator& f2, const const_iterator& l2)
Replaces the elements in the range [f1, l1) with the elements in the range [f2, l2).
void replace(const iterator& f1, const iterator& l1,
             const iterator& f2, const iterator& l2)
Replaces the elements in the range [f1, l1) with the elements in the range [f2, l2).
void replace(const iterator& p, const rope& x) | Replaces the element pointed to by p with the elements in x.
void replace(const iterator& p, charT c) | Replaces the element pointed to by p with the single character c.
void replace(const iterator& p, const charT* s) | Replaces the element pointed to by p with a C string: the sequence of characters beginning with *s and up to, but not including, the first null character.
void replace(const iterator& p, const charT* s, size_t n) | Replaces the element pointed to by p with the elements in the range [s, s + n).
void replace(const iterator& p,
             const charT* f, const charT* l)
Replaces the element pointed to by p with the elements in the range [f, l).
void replace(const iterator& p,
             const_iterator f, const_iterator l)
Replaces the element pointed to by p with the elements in the range [f, l).
void replace(const iterator& p,
             iterator f, iterator l)
Replaces the element pointed to by p with the elements in the range [f, l).
void replace(size_t i, size_t n, const rope& x) | Replaces the n elements beginning with the ith element with the elements in x.
void replace(size_t i, size_t n, charT c) | Replaces the n elements beginning with the ith element with the single character c.
void replace(size_t i, size_t n, const charT* s) | Replaces the n elements beginning with the ith element with an array of charT: the sequence of characters beginning with *s and up to, but not including, the first null character.
void replace(size_t i, size_t n1, const charT* s, size_t n2) | Replaces the n1 elements beginning with the ith element with the elements in the range [s, s + n2).
void replace(size_t i, size_t n,
             const charT* f, const charT* l)
Replaces the n elements beginning with the ith element with the characters in the range [f, l).
void replace(size_t i, size_t n,
             const const_iterator& f,
             const const_iterator& l)
Replaces the n elements beginning with the ith element with the characters in the range [f, l).
void replace(size_t i, size_t n,
             const iterator& f,
             const iterator& l)
Replaces the n elements beginning with the ith element with the characters in the range [f, l).
void replace(size_t i, charT c) | Replaces the ith element with the character c.
void replace(size_t i, const rope& x) | Replaces the ith element with elements from the rope x.
void replace(size_t i, const charT* s) | Replaces the ith element with a C string: the sequence of characters beginning with *s and up to, but not including, the first null character.
void replace(size_t i, const charT* s, size_t n) | Replaces the ith element with the elements in the range [s, s + n).
void replace(size_t i, const charT* f, const charT* l) | Replaces the ith element with the range [f, l).
void replace(size_t i,
             const const_iterator& f, const const_iterator& l)
Replaces the ith element with the range [f, l).
void replace(size_t i,
             const iterator& f, const iterator& l)
Replaces the ith element with the range [f, l).
rope substr(iterator f) const | Returns a new rope with a single element, *f. [4]
rope substr(const_iterator f) const | Returns a new rope with a single element, *f. [4]
rope substr(iterator f, iterator l) const | Returns a new rope that consists of the range [f, l). [4]
rope substr(const_iterator f, const_iterator l) const | Returns a new rope that consists of the range [f, l). [4]
rope substr(size_t i, size_t n = 1) const | Returns a new rope whose elements are the n characters starting at the position i. [4].
void copy(charT* buf) const | Copies the characters in a rope into buf.
size_type copy(size_type pos, size_type n,
               charT* buf)
Copies n characters, starting at position pos in the rope, into buf. If the rope contains fewer than pos + n characters, then instead it only copies size() - pos characters.
const charT* c_str() const | Returns a pointer to a null-terminated sequence of characters that contains all of the characters in a rope. [5] [6] The resulting sequence of characters is valid at least as long as the rope remains valid and unchanged. Note that the first invocation of this operation on long strings is slow: it is linear in the length of the rope.
void delete_c_str() | Reclaims the internal storage used by c_str. Note that this invalidates the pointer that c_str returns.
rope operator+(const rope& L, const rope& R) | Returns a new rope consisting of the concatenation of L and R. This is a global function, not a member function.
rope& operator+=(rope& L, const rope& R) | Modifies L by appending R, and returns L. This is a global function, not a member function.
rope operator+(const rope& L, const charT* s) | Returns a new rope consisting of the concatenation of L and all of the characters from s up to, but not including, the first null character. This is a global function, not a member function.
rope& operator+=(rope& L, const charT* s) | Modifies L by appending the characters from s up to, but not including, the first null character. The return value is L. This is a global function, not a member function.
rope operator+(const rope& L, charT c) | Returns a new rope consisting of L with the character c appended to it. This is a global function, not a member function.
rope& operator+=(rope& L, charT c) | Modifies L by appending the character c. This is a global function, not a member function.
ostream& operator<<(ostream& os, rope x) | Outputs x to the stream os. This is a global function, not a member function.

Notes

[1] For a detailed discussion of the rope data structure, see H.-J. Boehm, R. Atkinson, and M. Plass, "Ropes: An Alternative to Strings", Software Practice and Experience 25(12):1315, 1995.

[2] Since the value type is usually either char or wchar_t, the library introduces two abbreviations: crope is a typedef for rope<char>, and wrope is a typedef for rope<wchar_t>.

[3] Rope::reference is not value_type&, but a proxy type. In fact, reference is a typedef for the nested class charT_ref_proxy. Const_reference, however, is simply const value_type&. Similarly, const_pointer is just const value_type* but pointer is a proxy type. If r is an object of type reference, then &r is of type pointer.

[4] Note that the return value of substr is conceptually a distinct rope: the two ropes may share storage, but this is a hidden implementation detail. If you modify a rope returned by substr, this will not change the value of the original rope.

[5] The final const qualifier in the member function c_str() is conceptually slightly inaccurate in the interest of conformance to the basic_string interface in the draft C++ standard; the rope is updated to cache the converted string.

[6] Concurrent calls to c_str() are allowed; the cache is updated atomically.

See also

Random Access Container, Sequence, vector, sequence_buffer


Rope Implementation Overview

The rope container type included in SGI's version of the STL is based loosely on the ropes in the Xerox Cedar environment or C "cords", as described in Boehm, Atkinson, and Plass, "Ropes: An Alternative to Strings", Software Practice and Experience 25, 12 (Dec 1995), pp. 1315 - 1330.

A rope is represented as a pointer to _Rope_RopeRep structure, which represents a tree node. Every tree node corresponds to a piece of a rope. Although we refer to "tree nodes", each such piece can be shared between different ropes, or can even be reused in the same rope if the corresponding substring is repeated. Thus ropes are really represented as directed acyclic graphs. Nonetheless, we will continue to refer to trees, since that is both the usual case, and more intuitive.

Each tree node contains a size field giving the length of the rope piece, a depth field specifying the depth (or height) of the tree rooted at the node, a boolean field indicating whether the subtree has been balanced, and a tag field indicating which of the four variants or subclasses of _Rope_RopeRep is used to represent the list. (The balanced bit is really of interest only for concatenation tree nodes, see below.)

It would have been possible to use virtual functions and/or RTTI to replace the use of the tag field. We chose not to pursue that route, since the tag field can be much smaller than a vtable pointer, and the tag based code is probably also faster in this case.

The 4 subclasses of _Rope_RopeRep are:

  1. (_Rope_RopeLeaf) Leaves containing string characters. Short ropes are usually represented as a single such node. In the case of the standard character type, the actual array of characters is NULL-terminated to allow fast generation of an equivalent C string.
  2. (_Rope_RopeConcatenation) Concatenation nodes. These have two children left and right. They represent the concatenation of the two strings represented by the left and right subtrees. Concatenation of two longer ropes usually allocates a new concatenation node which references the two ropes to be concatenated.
  3. (_Rope_RopeFunction) Function nodes. These contain a pointer to a function object that can be used to compute sections of the string. This facility makes it possible to manipulate a rope that is computed lazily as the pieces are needed. For example, it is possible to treat a file as a rope without actually reading in the entire file. Thus a text editor can represent even a 100 MB file being edited as a rope, updating it with standard rope operations, while still consuming only very small amount of memory.
  4. (_Rope_RopeSubstring) Substring nodes. These contain a pointer to a base rope tree node, and a starting position within that rope. They denote a substring of the base rope. These are generated only to represent substrings of ropes that are expensive to compute explicitly. The base field never points to a concatenation tree node. If the substring operation is applied to either a very large leaf node (which can be built by converting a very long C string to a rope) or to a function node representing a long string, then it produces a substring node. Substring nodes also contain a pointer to a function object that performs the appropriate character extraction. They are a subclass of function nodes, and a number of operations treat them simply as function nodes. Many uses of ropes will never result in the generation of a substring node. They are however essential for applications that use function nodes to lazily evaluate strings.

Only concatenation nodes have nonzero depth fields. Depth fields are guaranteed to fit into a byte, since we impose a static maximum on rope depth.

Reference Counting and Synchronization

The rope implementation can be compiled in two different ways. Normally __GC will not be defined. In this case each tree node will also contain a reference count field. This keeps track of the number of rope variables, concatenation nodes, or substring nodes that reference the tree node. (We'll see later that references from some iterators are also included.) When the reference count of a tree node becomes zero, the tree node is deallocated, and reference counts of any subtrees are correspondingly decremented.

In a few cases, the reference counts are also used to allow in-place updates of ropes. If the reference counts of all tree nodes on the path from a rope R's root node to the leaf node L holding a specific character are 1, then L occurs exactly once in R, and in no other rope. Thus R can safely be updated by updating L in place.

If the rope implementation is compiled with __GC defined, it will assume that there is an underlying garbage collector and inaccessible tree nodes will be automatically reclaimed. In this case rope must be instantiated with a suitable garbage-collecting allocator, and no reference count is maintained. Thus the above optimization for in-place updates is also not implemented. Since even non-destructive updates copy only portions of a rope, and since many rope clients will use them purely as immutable strings, this is often not a serious loss. But it may be for some applications.

The remainder of this section assumes that __GC is not defined, and that reference counts are used.

Since rope nodes can be shared by different ropes, which can be concurrently copied, updated, or destroyed by different threads, reference counts must be updated atomically. This is the only explicit synchronization performed by the implementation, since the reference count is the only part of a potentially shared data structure that is updated.

The synchronization required for reference count updates may consume a significant fraction of the time required for rope operations. Reference count updates should be implemented in terms of an atomic add operation whenever such an operation is available. It is important that the reference count decrement operation not only atomically decrement the count, but also return the result as part of the atomic operation. If the zero test is performed outside the atomic part of the operation, the same tree node may be deallocated twice.

On Irix and win32 platforms, the current implementation maintains reference counts using an atomic add operation. A more generic implementation based on PThread mutexes is also provided. But it is unlikely to provide optimal performance for applications that use ropes extensively.

Allocator Use

The rope implementation can use either standard-conforming allocators (compiler permitting) or SGI-style simplified allocators. In the former case and if there are distinct allocator instances of a given allocator type, the allocator instance is stored in each rope tree node, as well as in the rope itself. It is illegal to concatenate ropes built with different allocator instances.

This representation was chosen because it keeps the implementation comparatively clean, and the instance-less case reasonably efficient. The alternative of storing the allocator instance only in the rope would have added additional allocator arguments to many internal functions. It would have been difficult to eliminate this overhead for allocator types that do not have distinct instances.

Basic Algorithms and Rope Balancing

Concatenation is normally implemented by allocating a new concatenation node, and having it refer to the two arguments to the concatenation operation. Thus in most cases its execution time is independent of the length of strings.

The case in which a short rope consisting of a single leaf is concatenated onto the right of a rope which is either a leaf, or a concatenation node whose right child is a leaf, is handled specially. In this case, if the leaves in question are sufficiently short, we may either allocate a new leaf holding the combined contents of the two leaves or, under the right circumstances, even update the left operand in place. In order to allow the destructive update, the actual arrays holding leaf characters are grown in increments of 8.

For example, the rope "abcedefghigklmnopqrstuvwxy" might be concatenated to "z" as shown in the following figure:

Handling this case specially guarantees that ropes built by repeatedly concatenating short strings onto the right will be composed of leaves of a minimum size, and thus can be stored and processed efficiently. It has a similar effect on repeated character insertions in the same position.

Although concatenation is efficient independent of the shape of the tree, some other operations such as retrieving the ith character, are more efficient if the tree representing the rope is approximately balanced. Ropes can be rebalanced either via an explicit call to the balance member function, or implicitly as the result of a concatenation. Ropes are implicitly rebalanced whenever the depth is in danger of overflowing, or the rope both exceeds a smaller depth threshold (currently 20) and is below a minimum length (currently 1000).

The balance operation proceeds as described in the paper cited above. The operation is non-destructive; rebalanced pieces formerly shared with other ropes are no longer shared after the operation. As a rope is being balanced, the balanced bit is set in each concatenation node that has sufficiently small depth for its length. Tree nodes with the balanced bit set are not examined by further balancing operations. Thus the balance operation tends to not rebalance the same substring.

The worst-case cost of rebalancing is nonetheless linear in the string. However, the observed behavior is that rebalancing typically consumes a small fraction of the running time. Indeed, all natural ways of building a rope of length N by repeated concatenation require total time linear in N. It is possible, but nontrivial, to design concatenation sequences that violate this.

The substring operation is performed differently depending on the tree node representing the root of the rope. The operation is recursive:

  1. For a leaf node, we either return a leaf node with the substring, or if that would be too long, we return a subscript node.
  2. For a concatenation node, we return the concatenation of the appropriate substrings of the left and right subtrees. We stop if we find that we need a zero length substring. Similarly, we simply return a pointer to the entire rope when that's appropriate.
  3. For a substring node, we either return a short leaf node, or a new substring node. referring to the rope from which the original substring was obtained. Thus we do not build up nested substring nodes.
  4. Any other function node is treated roughly as a leaf.
Note that this process requires time proportional to the rope depth, and doesn't directly depend on the length. The algorithm only copies pieces of leaf nodes at the beginning and end of the substring, and it builds new concatenation nodes along the paths from the root to either end of the substring. The interior of the substring can remain shared with the original rope.

Iterators

Iterators generated by the normal begin() and end() operations generate const_iterators, i.e. iterators that do not permit updates to the underlying rope. Such iterators basically contain three kinds of information:

  1. A pointer to the root node of the rope with which the iterator is associated. This pointer is not included in the reference count, Const_iterators become invalid if the underlying rope is modified or destroyed. (In the garbage collected case they remain valid and continue to refer to the original pre-modification rope.)
  2. The position inside the rope.
  3. Cached information used to speed up access to sections of the rope close to the current position.
We maintain two kinds of cache information in the iterator:
  1. The limits of a contiguous block of storage holding the characters surrounding the current character position, and the current offset within that block. Most iterator references can be resolved with access to only this part of the cache. The referenced block of storage can either be part of a leaf in the rope representation, or it can be a small block of characters reserved inside the iterator itself. The latter is used when the iterator refers to a rope section represented by a function node.
  2. The bottom few rope nodes on the path from the root node to the leaf or function node currently referenced by the iterator. This is used to quickly increment or decrement the iterator across node boundaries. We do not cache the entire path, since that would make rope iterators unpleasantly large.

This implementation differs significantly from that used in the C "cord" package. We do not reserve space inside iterators for a complete path from the root to the current node. This change was made to accommodate STL code that assumes small iterators that can be cheaply passed by value. We try to aid such code further by providing an iterator assignment operation which does not copy the cache part of the iterator unless it has been initialized.

The character buffer in the iterator is needed since there is not another place to cache characters returned for the evaluation of a function node. (This is less of an issue with a garbage collector, since it turns out to be reasonably efficient to maintain such caches in the function object itself. Without a garbage collector, this requires locking around cache accesses, which is usually unacceptable.)

Mutable iterators differ primarily in that they also contain a pointer to the rope itself (i.e. a pointer to the tree node pointer), so that they can be used to perform updates, and in that the rope root pointer is included in the reference count. In this case the rope root pointer is redundant, except that it us used to detect changes in the rope, so that the cached information in the iterator can be invalidated. The rope has changed iff the rope itself no longer points to the same node as the rope root pointer in the iterator. The fact that the iterator is included in the reference count ensures that the root node cannot be dropped and reused. It also prevents the rope from being destructively updated while the iterator must remain valid.


rotate

Category: algorithms | Component type: function

Prototype

template <class ForwardIterator>
inline ForwardIterator rotate(ForwardIterator first, ForwardIterator middle,
                   ForwardIterator last);

Description

Rotate rotates the elements in a range. That is, the element pointed to by middle is moved to the position first, the element pointed to by middle + 1 is moved to the position first + 1, and so on. One way to think about this operation is that it exchanges the two ranges [first, middle) and [middle, last). Formally, for every integer n such that 0 <= n < last - first, the element *(first + n) is assigned to *(first + (n + (last - middle)) % (last - first)). Rotate returns first + (last - middle).

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

  • ForwardIterator is a model of Forward Iterator.
  • ForwardIterator is mutable.

Preconditions

  • [first, middle) is a valid range.
  • [middle, last) is a valid range. [1]

Complexity

Linear. At most last - first swaps are performed. [2]

Example

char alpha[] = "abcdefghijklmnopqrstuvwxyz";
rotate(alpha, alpha + 13, alpha + 26);
printf("%s\n", alpha);
// The output is nopqrstuvwxyzabcdefghijklm

Notes

[1] It follows from these two requirements that [first, last) is a valid range.

[2] Rotate uses a different algorithm depending on whether its arguments are Forward Iterators, Bidirectional Iterators, or Random Access Iterators. All three algorithms, however, are linear.

See also

rotate_copy


rotate_copy

Category: algorithms | Component type: function

Prototype

template <class ForwardIterator, class OutputIterator>
OutputIterator rotate_copy(ForwardIterator first, ForwardIterator middle,
                           ForwardIterator last, OutputIterator result);

Description

Rotate_copy copies elements from the range [first, last) to the range [result, result + (last - first)) such that *middle is copied to *result, *(middle + 1) is copied to *(result + 1), and so on. Formally, for every integer n such that 0 <= n < last - first, rotate_copy performs the assignment *(result + (n + (last - middle)) % (last - first)) = *(first + n). Rotate_copy is similar to copy followed by rotate, but is more efficient. The return value is result + (last - first).

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

  • ForwardIterator is a model of Forward Iterator.
  • OutputIterator is a model of Output Iterator.
  • ForwardIterator's value type is convertible to a type in OutputIterator's set of value types.

Preconditions

  • [first, middle) is a valid range.
  • [middle, last) is a valid range. [1]
  • There is enough space to hold all of the elements being copied. More formally, the requirement is that [result, result + (last - first)) is a valid range.
  • The ranges [first, last) and [result, result + (last - first)) do not overlap.

Complexity

Linear. Rotate_copy performs exactly last - first assignments.

Example

const char alpha[] = "abcdefghijklmnopqrstuvwxyz";
rotate_copy(alpha, alpha + 13, alpha + 26, ostream_iterator<char>(cout));
// The output is nopqrstuvwxyzabcdefghijklm

Notes

[1] It follows from these two requirements that [first, last) is a valid range.

See also

rotate, copy.


search

Category: algorithms | Component type: function

Prototype

Search is an overloaded name; there are actually two search functions.
template <class ForwardIterator1, class ForwardIterator2>
ForwardIterator1 search(ForwardIterator1 first1, ForwardIterator1 last1,
                        ForwardIterator2 first2, ForwardIterator2 last2);

template <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>
ForwardIterator1 search(ForwardIterator1 first1, ForwardIterator1 last1,
                        ForwardIterator2 first2, ForwardIterator2 last2,
                        BinaryPredicate binary_pred);

Description

Search finds a subsequence within the range [first1, last1) that is identical to [first2, last2) when compared element-by-element. It returns an iterator pointing to the beginning of that subsequence, or else last1 if no such subsequence exists. The two versions of search differ in how they determine whether two elements are the same: the first uses operator==, and the second uses the user-supplied function object binary_pred.

The first version of search returns the first iterator i in the range [first1, last1 - (last2 - first2)) [1] such that, for every iterator j in the range [first2, last2), *(i + (j - first2)) == *j. The second version returns the first iterator i in [first1, last1 - (last2 - first2)) such that, for every iterator j in [first2, last2), binary_pred(*(i + (j - first2)), *j) is true. These conditions simply mean that every element in the subrange beginning with i must be the same as the corresponding element in [first2, last2).

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

For the first version:
  • ForwardIterator1 is a model of Forward Iterator.
  • ForwardIterator2 is a model of Forward Iterator.
  • ForwardIterator1's value type is a model of EqualityComparable.
  • ForwardIterator2's value type is a model of EqualityComparable.
  • Objects of ForwardIterator1's value type can be compared for equality with Objects of ForwardIterator2's value type.
For the second version:
  • ForwardIterator1 is a model of Forward Iterator.
  • ForwardIterator2 is a model of Forward Iterator.
  • BinaryPredicate is a model of Binary Predicate.
  • ForwardIterator1's value type is convertible to BinaryPredicate's first argument type.
  • ForwardIterator2's value type is convertible to BinaryPredicate's second argument type.

Preconditions

  • [first1, last1) is a valid range.
  • [first2, last2) is a valid range.

Complexity

Worst case behavior is quadratic: at most (last1 - first1) * (last2 - first2) comparisons. This worst case, however, is rare. Average complexity is linear.

Example

  const char S1[] = "Hello, world!";
  const char S2[] = "world";
  const int N1 = sizeof(S1) - 1;
  const int N2 = sizeof(S2) - 1;

  const char* p = search(S1, S1 + N1, S2, S2 + N2);
  printf("Found subsequence \"%s\" at character %d of sequence \"%s\".\n",
         S2, p - S1, S1);

Notes

[1] The reason that this range is [first1, last1 - (last2 - first2)), instead of simply [first1, last1), is that we are looking for a subsequence that is equal to the complete sequence [first2, last2). An iterator i can't be the beginning of such a subsequence unless last1 - i is greater than or equal to last2 - first2. Note the implication of this: you may call search with arguments such that last1 - first1 is less than last2 - first2, but such a search will always fail.

See also

find, find_if, find_end, search_n, mismatch, equal


search_n

Category: algorithms | Component type: function

Prototype

Search_n is an overloaded name; there are actually two search_n functions.
template <class ForwardIterator, class Integer, class T>
ForwardIterator search_n(ForwardIterator first, ForwardIterator last,
                         Integer count, const T& value);

template <class ForwardIterator, class Integer,
          class T, class BinaryPredicate>
ForwardIterator search_n(ForwardIterator first, ForwardIterator last,
                         Integer count, const T& value,
                         BinaryPredicate binary_pred);

Description

Search_n searches for a subsequence of count consecutive elements in the range [first, last), all of which are equal to value. [1] It returns an iterator pointing to the beginning of that subsequence, or else last if no such subsequence exists. The two versions of search_n differ in how they determine whether two elements are the same: the first uses operator==, and the second uses the user-supplied function object binary_pred.

The first version of search returns the first iterator i in the range [first, last - count) [2] such that, for every iterator j in the range [i, i + count), *j == value. The second version returns the first iterator i in the range [first, last - count) such that, for every iterator j in the range [i, i + count), binary_pred(*j, value) is true.

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

For the first version:
  • ForwardIterator is a model of Forward Iterator.
  • Integer is an integral type.
  • T is a model of EqualityComparable.
  • ForwardIterator's value type is a model of EqualityComparable.
  • Objects of ForwardIterator's value type can be compared for equality with Objects of type T.
For the first version:
  • ForwardIterator is a model of Forward Iterator.
  • Integer is an integral type.
  • T is a model of EqualityComparable.
  • BinaryPredicate is a model of Binary Predicate.
  • ForwardIterator's value type is convertible to BinaryPredicate's first argument type.
  • T is convertible to BinaryPredicate's second argument type.

Preconditions

  • [first, last) is a valid range.
  • count is non-negative [1].

Complexity

Linear. Search_n performs at most last - first comparisons.

(The C++ standard permits the complexity to be O(n (last - first)), but this is unnecessarily lax. There is no reason for search_n to examine any element more than once.)

Example

bool eq_nosign(int x, int y) { return abs(x) == abs(y); }

void lookup(int* first, int* last, size_t count, int val) {
  cout << "Searching for a sequence of "
       << count
       << " '" << val << "'"
       << (count != 1 ? "s: " : ":  ");
  int* result = search_n(first, last, count, val);
  if (result == last)
    cout << "Not found" << endl;
  else
    cout << "Index = " << result - first << endl;
}

void lookup_nosign(int* first, int* last, size_t count, int val) {
  cout << "Searching for a (sign-insensitive) sequence of "
       << count
       << " '" << val << "'"
       << (count != 1 ? "s: " : ":  ");
  int* result = search_n(first, last, count, val, eq_nosign);
  if (result == last)
    cout << "Not found" << endl;
  else
    cout << "Index = " << result - first << endl;
}

int main() {
  const int N = 10;
  int A[N] = {1, 2, 1, 1, 3, -3, 1, 1, 1, 1};

  lookup(A, A+N, 1, 4);
  lookup(A, A+N, 0, 4);
  lookup(A, A+N, 1, 1);
  lookup(A, A+N, 2, 1);
  lookup(A, A+N, 3, 1);
  lookup(A, A+N, 4, 1);

  lookup(A, A+N, 1, 3);
  lookup(A, A+N, 2, 3);
  lookup_nosign(A, A+N, 1, 3);
  lookup_nosign(A, A+N, 2, 3);
}

The output is

Searching for a sequence of 1 '4':  Not found
Searching for a sequence of 0 '4's: Index = 0
Searching for a sequence of 1 '1':  Index = 0
Searching for a sequence of 2 '1's: Index = 2
Searching for a sequence of 3 '1's: Index = 6
Searching for a sequence of 4 '1's: Index = 6
Searching for a sequence of 1 '3':  Index = 4
Searching for a sequence of 2 '3's: Not found
Searching for a (sign-insensitive) sequence of 1 '3':  Index = 4
Searching for a (sign-insensitive) sequence of 2 '3's: Index = 4

Notes

[1] Note that count is permitted to be zero: a subsequence of zero elements is well defined. If you call search_n with count equal to zero, then the search will always succeed: no matter what value is, every range contains a subrange of zero consecutive elements that are equal to value. When search_n is called with count equal to zero, the return value is always first.

[2] The reason that this range is [first, last - count), rather than just [first, last), is that we are looking for a subsequence whose length is count; an iterator i can't be the beginning of such a subsequence unless last - count is greater than or equal to count. Note the implication of this: you may call search_n with arguments such that last - first is less than count, but such a search will always fail.

See also

search, find_end, find, find_if


select1st<Pair>

Category: functors | Component type: type

Description

Select1st is a function object that takes a single argument, a pair [1], and returns the pair's first element.

Example

Print all of a map's keys.
int main()
{
  map<int, double> M;
  M[1] = 0.3;
  M[47] = 0.8;
  M[33] = 0.1;

  transform(M.begin(), M.end(), ostream_iterator<int>(cout, " "),
            select1st<map<int, double>::value_type>());
  // The output is  1 33 47.
}

Definition

Defined in the standard header functional, and in the nonstandard backward-compatibility header function.h. This function object is an SGI extension; it is not part of the C++ standard.

Template parameters

Parameter | Description | Default
Pair | The function object's argument type. |

Model of

Adaptable Unary Function Adaptable Unary Function Adaptable Unary Function

Type requirements

There exist some types U and V such that Pair provides the same interface as a pair<U,V>. [1]

Public base classes

unary_function<Pair, Pair::first_type>

Members

Member | Where defined | Description
argument_type | Adaptable Unary Function | The type of select1st's argument: Pair
result_type | Adaptable Unary Function | The type of the result: Pair::first_type
const Pair::first_type&
operator()(const Pair& p) const
Adaptable Unary Function Function call. The return value is p.first.

New members

All of select1st's members are defined in the Adaptable Unary Function requirements. Select1st does not introduce any new members.

Notes

[1] Pair is not actually required to be a pair<U,V>, but merely to support the same interface as pair. In almost all cases the template parameter will be a pair, but it is occasionally useful for it to be something else. One example is a struct that has the members first, second, and third.

See also

identity, select2nd, project1st, project2nd


select2nd<Pair>

Category: functors | Component type: type

Description

Select2nd is a function object that takes a single argument, a pair [1], and returns the pair's second element.

Example

Print all of a map's values.
int main()
{
  map<int, double> M;
  M[1] = 0.3;
  M[47] = 0.8;
  M[33] = 0.1;

  transform(M.begin(), M.end(), ostream_iterator<double>(cout, " "),
            select2nd<map<int, double>::value_type>());
  // The output is  0.3 0.1 0.8
}

Definition

Defined in the standard header functional, and in the nonstandard backward-compatibility header function.h. This function object is an SGI extension; it is not part of the C++ standard.

Template parameters

Parameter | Description | Default
Pair | The function object's argument type. |

Model of

Adaptable Unary Function

Type requirements

There exist some types U and V such that Pair provides the same interface as a pair<U,V>. [1]

Public base classes

unary_function<Pair, Pair::second_type>

Members

Member | Where defined | Description
argument_type | Adaptable Unary Function | The type of select2nd's argument: Pair
result_type | Adaptable Unary Function | The type of the result: Pair::second_type
const Pair::second_type&
operator()(const Pair& p) const
Adaptable Unary Function Function call. The return value is p.second.

New members

All of select2nd's members are defined in the Adaptable Unary Function requirements. Select2nd does not introduce any new members.

Notes

[1] Pair is not actually required to be a pair<U,V>, but merely to support the same interface as pair. In almost all cases the template parameter will be a pair, but it is occasionally useful for it to be something else. One example is a struct that has the members first, second, and third.

See also

identity, select1st, project1st, project2nd


Sequence

Category: containers | Component type: concept

Description

A Sequence is a variable-sized Container whose elements are arranged in a strict linear order. It supports insertion and removal of elements.

Refinement of

Forward Container, Default Constructible

Associated types

None, except for those of Forward Container.

Notation

X | A type that is a model of Sequence
a, b | Object of type X
T | The value type of X
t | Object of type T
p, q | Object of type X::iterator
n | Object of a type convertible to X::size_type

Definitions

If a is a Sequence, then p is a valid iterator in a if it is a valid (nonsingular) iterator that is reachable from a.begin().

If a is a Sequence, then [p, q) is a valid range in a if p and q are valid iterators in a and if q is reachable from p.

Valid expressions

In addition to the expressions defined in Forward Container, the following expressions must be valid.
Name | Expression | Type requirements | Return type
Fill constructor | X(n, t) |  | X
Fill constructor | X a(n, t); |  |
Default fill constructor | X(n) | T is DefaultConstructible. | X
Default fill constructor | X a(n); | T is DefaultConstructible. |
Range constructor | X(i, j) | i and j are Input Iterators whose value type is convertible to T [1] | X
Range constructor | X a(i, j); | i and j are Input Iterators whose value type is convertible to T [1] |
Front | a.front() |  | reference if a is mutable, const_reference otherwise.
Insert | a.insert(p, t) |  | X::iterator
Fill insert | a.insert(p, n, t) | a is mutable | void
Range insert | a.insert(p, i, j) | i and j are Input Iterators whose value type is convertible to T [1]. a is mutable | void
Erase | a.erase(p) | a is mutable | iterator
Range erase | a.erase(p,q) | a is mutable | iterator
Clear | a.clear() | a is mutable | void
Resize | a.resize(n, t) | a is mutable | void
Resize | a.resize(n) | a is mutable | void

Expression semantics

Semantics of an expression is defined only where it is not defined in Forward Container, or where it differs.
Name | Expression | Precondition | Semantics | Postcondition
Fill constructor | X(n, t) | n >= 0 | Creates a sequence with n copies of t | size() == n. Every element is a copy of t.
Fill constructor | X a(n, t); | n >= 0 | Creates a sequence with n copies of t | a.size() == n. Every element of a is a copy of t.
Default fill constructor | X(n) | n >= 0 | Creates a sequence of n elements initialized to a default value. | size() == n. Every element is a copy of T().
Default fill constructor | X a(n, t); | n >= 0 | Creates a sequence with n elements initialized to a default value. | a.size() == n. Every element of a is a copy of T().
Default constructor | X a; or X() |  | Equivalent to X(0). | size() == 0.
Range constructor | X(i, j) | [i,j) is a valid range. | Creates a sequence that is a copy of the range [i,j) | size() is equal to the distance from i to j. Each element is a copy of the corresponding element in the range [i,j).
Range constructor | X a(i, j); | [i,j) is a valid range. | Creates a sequence that is a copy of the range [i,j) | a.size() is equal to the distance from i to j. Each element in a is a copy of the corresponding element in the range [i,j).
Front | a.front() | !a.empty() | Equivalent to *(a.first()) |
Insert | a.insert(p, t) | p is a valid iterator in a. a.size() < a.max_size() | A copy of t is inserted before p. [2] [3] | a.size() is incremented by 1. *(a.insert(p,t)) is a copy of t. The relative order of elements already in the sequence is unchanged.
Fill insert | a.insert(p, n, t) | p is a valid iterator in a. n >= 0 && a.size() + n <= a.max_size(). | n copies of t are inserted before p. [2] [3] [4] | a.size() is incremented by n. The relative order of elements already in the sequence is unchanged.
Range insert | a.insert(p, i, j) | [i,j) is a valid range. a.size() plus the distance from i to j does not exceed a.max_size(). | Inserts a copy of the range [i,j) before p. [1] [2] [3] | a.size() is incremented by the distance from i to j. The relative order of elements already in the sequence is unchanged.
Erase | a.erase(p) | p is a dereferenceable iterator in a. | Destroys the element pointed to by p and removes it from a. [3] | a.size() is decremented by 1. The relative order of the other elements in the sequence is unchanged. The return value is an iterator to the element immediately following the one that was erased.
Range erase | a.erase(p,q) | [p,q) is a valid range in a. | Destroys the elements in the range [p,q) and removes them from a. [3] | a.size() is decremented by the distance from i to j. The relative order of the other elements in the sequence is unchanged. The return value is an iterator to the element immediately following the ones that were erased.
Clear | a.clear() |  | Equivalent to a.erase(a.begin(), a.end()) |
Resize | a.resize(n, t) | n <= a.max_size() | Modifies the container so that it has exactly n elements, inserting elements at the end or erasing elements from the end if necessary. If any elements are inserted, they are copies of t. If n > a.size(), this expression is equivalent to a.insert(a.end(), n - size(), t). If n < a.size(), it is equivalent to a.erase(a.begin() + n, a.end()). | a.size() == n
Resize | a.resize(n) | n <= a.max_size() | Equivalent to a.resize(n, T()). | a.size() == n

Complexity guarantees

The fill constructor, default fill constructor, and range constructor are linear.

Front is amortized constant time.

Fill insert, range insert, and range erase are linear.

The complexities of single-element insert and erase are sequence dependent.

Invariants

Models

  • vector [5]
  • deque
  • list
  • slist

Notes

[1] At present (early 1998), not all compilers support "member templates". If your compiler supports member templates then i and j may be of any type that conforms to the Input Iterator requirements. If your compiler does not yet support member templates, however, then i and j must be of type const T* or of type X::const_iterator.

[2] Note that p equal to a.begin() means to insert something at the beginning of a (that is, before any elements already in a), and p equal to a.end() means to append something to the end of a.

[3] Warning: there is no guarantee that a valid iterator on a is still valid after an insertion or an erasure. In some cases iterators do remain valid, and in other cases they do not. The details are different for each sequence class.

[4] a.insert(p, n, t) is guaranteed to be no slower then calling a.insert(p, t) n times. In some cases it is significantly faster.

[5] Vector is usually preferable to deque and list. Deque is useful in the case of frequent insertions at both the beginning and end of the sequence, and list and slist are useful in the case of frequent insertions in the middle of the sequence. In almost all other situations, vector is more efficient.

See also

Container, Forward Container, Associative Container, Front Insertion Sequence, Back Insertion Sequence, vector, deque, list, slist


sequence_buffer<Container, buf_sz>

Categories: iterators, adaptors | Component type: type

Description

Sequence_buffer is similar to back_insert_iterator: it is an output iterator adaptor that appends elements to the end of a container.

The main difference between sequence_buffer and back_insert_iterator is that back_insert_iterator inserts elements into a sequence one element at a time; sequence_buffer, however, as the "buffer" part of the name suggests, accumulates elements into a buffer and appends the entire buffer in a single operation.

Specifically, the expression *it = v adds v to the end of it's internal buffer. The buffer is automatically flushed when it gets full, or when it is destroyed; flushing the buffer means emptying it and appending its contents to it's underlying container. (It is also possible to flush the buffer manually, by invoking the flush() member function.)

This difference has two implications. First, sequence_buffer is only useful if appending an array of N elements is much more efficient than inserting a single element N times. Second, sequence_buffer assumes that it can insert elements at the end of a container using an append member function. This member function is not part of the Container or Sequence requirements. The sequence_buffer adaptor can be used with rope, but not with any of the other containers in the library. (This is the reason why sequence_buffer is defined in the file rope.h, instead of in iterator.h.)

If you want to build up a string one character at a time, it is much more efficient to use sequence_buffer than to repeatedly add single characters to the end of a rope.

Example

int main()
{
  const char* const s = "this is a test";
  const int N = strlen(s);

  crope r;
  transform(s, s + N,
            sequence_buffer<crope>(r),
            toupper);
  cout << "r = " << r << endl;
}

Definition

Defined in the header rope, and in the backward-compatibility header rope.h. The sequence_buffer class, and the rope header, are SGI extensions; they are not part of the C++ standard.

Template parameters

Parameter | Description | Default
Container | The type of the underlying container that elements are being written to. [1] |
buf_sz | Number of elements in the buffer. This is a number, not a type. buf_sz has type size_t. | 100

Model of

Output Iterator.

Type requirements

  • Container is a variable-sized Forward Container
  • Container's value type T is a model of Default Constructible, as well as Assignable.
  • Container has a member function that appends a range. Specifically: If x is an object of type Container and f and l are of type T*, then x.append(f, l) appends the range [f, l) to x. [1]

Public base classes

output_iterator

Members

Member | Where defined | Description
value_type | sequence_buffer | The underlying container's value type.
sequence_buffer(Container& C) | sequence_buffer | Create a sequence_buffer whose underlying container is C.
sequence_buffer() | Default Constructible | The default constructor. The resulting iterator is singular.
sequence_buffer(const sequence_buffer&) | Assignable | Copy constructor.
sequence_buffer& operator=(const sequence_buffer& s) | Assignable | Assignment operator.
sequence_buffer& operator=(sequence_buffer& s) | Assignable | Faster version of assignment operator.
sequence_buffer& operator=(const value_type&) | Output Iterator | Used to implement the Output Iterator requirement *i = t. [2]
sequence_buffer& operator*() | Output Iterator | Used to implement the Output Iterator requirement *i = t. [2]
sequence_buffer& operator++() | Output Iterator | Preincrement
sequence_buffer& operator++(int) | Output Iterator | Postincrement
void flush() | sequence_buffer | Flush the buffer.
void push_back(value_type) | sequence_buffer | i.push_back(x) is equivalent to *i = x.
void append(value_type* s, size_t len) | sequence_buffer | Append multiple values.

New members

These members are not defined in the Output Iterator requirements, but are specific to sequence_buffer.
Function | Description
value_type | The underlying container's value type. That is, typename Container::value_type.
sequence_buffer(Container& C) | Create a sequence_buffer whose underlying container is C. Elements appended to the sequence_buffer will be appended to C whenever the sequence_buffer is flushed.
void flush() | Append all elements in the buffer to the underlying container, and empty the buffer. That is, make the underlying container consistent with the sequence_buffer. Note that flush is called automatically whenever the buffer is full, and also by sequence_buffer's destructor. Sometimes, however, it is useful to be sure that the buffer is flushed at a particular time.
void push_back(value_type x) | Append x to the sequence_buffer. Note that this member function is strictly unnecessary: i.push_back(x) is just alternate syntax for *i = x.
void append(value_type* s, size_t len) | Append the range [s, s + len) to the sequence_buffer. Note that i.append(s, n) is just the same as copy(s, s + n, i). The append member function, however, is faster.

Notes

[1] Despite the name "sequence_buffer", this adaptor cannot actually be used with arbitrary sequences: it requires that the template argument Container have an append member function that can insert multiple elements at the end of the container. This member function is not part of the Sequence requirements. This means that sequence_buffer can be used with rope, but not with any of the other predefined container classes.

[2] Note how assignment through a sequence_buffer is implemented. In general, unary operator* must be defined so that it returns a proxy object, where the proxy object defines operator= to perform the output operation. In this case, for the sake of simplicity, the proxy object is the sequence_buffer itself. That is, *i simply returns i, and *i = t is equivalent to i = t. You should not, however, rely on this behavior. It is an implementation detail, and it is not guaranteed to remain the same in future versions.

See also

Output Iterator, rope, front_insert_iterator, back_insert_iterator, insert_iterator


set<Key, Compare, Alloc>

Category: containers | Component type: type

Description

Set is a Sorted Associative Container that stores objects of type Key. Set is a Simple Associative Container, meaning that its value type, as well as its key type, is Key. It is also a Unique Associative Container, meaning that no two elements are the same.

Set and multiset are particularly well suited to the set algorithms includes, set_union, set_intersection, set_difference, and set_symmetric_difference. The reason for this is twofold. First, the set algorithms require their arguments to be sorted ranges, and, since set and multiset are Sorted Associative Containers, their elements are always sorted in ascending order. Second, the output range of these algorithms is always sorted, and inserting a sorted range into a set or multiset is a fast operation: the Unique Sorted Associative Container and Multiple Sorted Associative Container requirements guarantee that inserting a range takes only linear time if the range is already sorted.

Set has the important property that inserting a new element into a set does not invalidate iterators that point to existing elements. Erasing an element from a set also does not invalidate any iterators, except, of course, for iterators that actually point to the element that is being erased.

Example

struct ltstr
{
  bool operator()(const char* s1, const char* s2) const
  {
    return strcmp(s1, s2) < 0;
  }
};

int main()
{
  const int N = 6;
  const char* a[N] = {"isomer", "ephemeral", "prosaic",
                      "nugatory", "artichoke", "serif"};
  const char* b[N] = {"flat", "this", "artichoke",
                      "frigate", "prosaic", "isomer"};

  set<const char*, ltstr> A(a, a + N);
  set<const char*, ltstr> B(b, b + N);
  set<const char*, ltstr> C;

  cout << "Set A: ";
  copy(A.begin(), A.end(), ostream_iterator<const char*>(cout, " "));
  cout << endl;
  cout << "Set B: ";
  copy(B.begin(), B.end(), ostream_iterator<const char*>(cout, " "));
  cout << endl;

  cout << "Union: ";
  set_union(A.begin(), A.end(), B.begin(), B.end(),
            ostream_iterator<const char*>(cout, " "),
            ltstr());
  cout << endl;

  cout << "Intersection: ";
  set_intersection(A.begin(), A.end(), B.begin(), B.end(),
                   ostream_iterator<const char*>(cout, " "),
                   ltstr());
  cout << endl;

  set_difference(A.begin(), A.end(), B.begin(), B.end(),
                 inserter(C, C.begin()),
                 ltstr());
  cout << "Set C (difference of A and B): ";
  copy(C.begin(), C.end(), ostream_iterator<const char*>(cout, " "));
  cout << endl;
}

Definition

Defined in the standard header set, and in the nonstandard backward-compatibility header set.h.

Template parameters

Parameter | Description | Default
Key | The set's key type and value type. This is also defined as set::key_type and set::value_type |
Compare | The key comparison function, a Strict Weak Ordering whose argument type is key_type; it returns true if its first argument is less than its second argument, and false otherwise. This is also defined as set::key_compare and set::value_compare. | less<Key>
Alloc | The set's allocator, used for all internal memory management. | alloc

Model of

Unique Sorted Associative Container, Simple Associative Container

Type requirements

  • Key is Assignable.
  • Compare is a Strict Weak Ordering whose argument type is Key.
  • Alloc is an Allocator.

Public base classes

None.

Members

Member | Where defined | Description
value_type | Container | The type of object, T, stored in the set.
key_type | Associative Container | The key type associated with value_type.
key_compare | Sorted Associative Container | Function object that compares two keys for ordering.
value_compare | Sorted Associative Container | Function object that compares two values for ordering.
pointer | Container | Pointer to T.
reference | Container | Reference to T
const_reference | Container | Const reference to T
size_type | Container | An unsigned integral type.
difference_type | Container | A signed integral type.
iterator | Container | Iterator used to iterate through a set.
const_iterator | Container | Const iterator used to iterate through a set. (Iterator and const_iterator are the same type.)
reverse_iterator | Reversible Container | Iterator used to iterate backwards through a set.
const_reverse_iterator | Reversible Container | Const iterator used to iterate backwards through a set. (Reverse_iterator and const_reverse_iterator are the same type.)
iterator begin() const | Container | Returns an iterator pointing to the beginning of the set.
iterator end() const | Container | Returns an iterator pointing to the end of the set.
reverse_iterator rbegin() const | Reversible Container | Returns a reverse_iterator pointing to the beginning of the reversed set.
reverse_iterator rend() const | Reversible Container | Returns a reverse_iterator pointing to the end of the reversed set.
size_type size() const | Container | Returns the size of the set.
size_type max_size() const | Container | Returns the largest possible size of the set.
bool empty() const | Container | true if the set's size is 0.
key_compare key_comp() const | Sorted Associative Container | Returns the key_compare object used by the set.
value_compare value_comp() const | Sorted Associative Container | Returns the value_compare object used by the set.
set() | Container | Creates an empty set.
set(const key_compare& comp) | Sorted Associative Container | Creates an empty set, using comp as the key_compare object.
template <class InputIterator>
set(InputIterator f, InputIterator l)
[1]
Unique Sorted Associative Container Creates a set with a copy of a range.
template <class InputIterator>
set(InputIterator f, InputIterator l,
    const key_compare& comp)
[1]
Unique Sorted Associative Container Creates a set with a copy of a range, using comp as the key_compare object.
set(const set&) | Container | The copy constructor.
set& operator=(const set&) | Container | The assignment operator
void swap(set&) | Container | Swaps the contents of two sets.
pair<iterator, bool>
insert(const value_type& x)
Unique Associative Container Inserts x into the set.
iterator insert(iterator pos,
                const value_type& x)
Unique Sorted Associative Container Inserts x into the set, using pos as a hint to where it will be inserted.
template <class InputIterator>
void insert(InputIterator, InputIterator)
[1]
Unique Sorted Associative Container Inserts a range into the set.
void erase(iterator pos) | Associative Container | Erases the element pointed to by pos.
size_type erase(const key_type& k) | Associative Container | Erases the element whose key is k.
void erase(iterator first, iterator last) | Associative Container | Erases all elements in a range.
void clear() | Associative Container | Erases all of the elements.
iterator find(const key_type& k) const | Associative Container | Finds an element whose key is k.
size_type count(const key_type& k) const | Unique Associative Container | Counts the number of elements whose key is k.
iterator lower_bound(const key_type& k) const | Sorted Associative Container | Finds the first element whose key is not less than k.
iterator upper_bound(const key_type& k) const | Sorted Associative Container | Finds the first element whose key greater than k.
pair<iterator, iterator>
equal_range(const key_type& k) const
Sorted Associative Container Finds a range containing all elements whose key is k.
bool operator==(const set&,
                const set&)
Forward Container Tests two sets for equality. This is a global function, not a member function.
bool operator<(const set&,
               const set&)
Forward Container Lexicographical comparison. This is a global function, not a member function.

New members

All of set's members are defined in the Unique Sorted Associative Container and Simple Associative Container requirements. Set does not introduce any new members.

Notes

[1] This member function relies on member template functions, which at present (early 1998) are not supported by all compilers. If your compiler supports member templates, you can call this function with any type of input iterator. If your compiler does not yet support member templates, though, then the arguments must either be of type const value_type* or of type set::const_iterator.

See also

Associative Container, Sorted Associative Container, Simple Associative Container, Unique Sorted Associative Container, map, multiset, multimap, hash_set, hash_map, hash_multiset, hash_multimap


set_difference

Category: algorithms | Component type: function

Prototype

Set_difference is an overloaded name; there are actually two set_difference functions.
template <class InputIterator1, class InputIterator2, class OutputIterator>
OutputIterator set_difference(InputIterator1 first1, InputIterator1 last1,
                              InputIterator2 first2, InputIterator2 last2,
                              OutputIterator result);

template <class InputIterator1, class InputIterator2, class OutputIterator,
          class StrictWeakOrdering>
OutputIterator set_difference(InputIterator1 first1, InputIterator1 last1,
                              InputIterator2 first2, InputIterator2 last2,
                              OutputIterator result,
                              StrictWeakOrdering comp);

Description

Set_difference constructs a sorted range that is the set difference of the sorted ranges [first1, last1) and [first2, last2). The return value is the end of the output range.

In the simplest case, set_difference performs the "difference" operation from set theory: the output range contains a copy of every element that is contained in [first1, last1) and not contained in [first2, last2). The general case is more complicated, because the input ranges may contain duplicate elements. The generalization is that if a value appears m times in [first1, last1) and n times in [first2, last2) (where m or n may be zero), then it appears max(m-n, 0) times in the output range. [1] Set_difference is stable, meaning both that elements are copied from the first range rather than the second, and that the relative order of elements in the output range is the same as in the first input range.

The two versions of set_difference differ in how they define whether one element is less than another. The first version compares objects using operator<, and the second compares objects using a function object comp.

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

For the first version:
  • InputIterator1 is a model of Input Iterator.
  • InputIterator2 is a model of Input Iterator.
  • OutputIterator is a model of Output Iterator.
  • InputIterator1 and InputIterator2 have the same value type.
  • InputIterator's value type is a model of LessThan Comparable.
  • The ordering on objects of InputIterator1's value type is a strict weak ordering, as defined in the LessThan Comparable requirements.
  • InputIterator's value type is convertible to a type in OutputIterator's set of value types.
For the second version:
  • InputIterator1 is a model of Input Iterator.
  • InputIterator2 is a model of Input Iterator.
  • OutputIterator is a model of Output Iterator.
  • StrictWeakOrdering is a model of Strict Weak Ordering.
  • InputIterator1 and InputIterator2 have the same value type.
  • InputIterator1's value type is convertible to StrictWeakOrdering's argument type.
  • InputIterator's value type is convertible to a type in OutputIterator's set of value types.

Preconditions

For the first version:
  • [first1, last1) is a valid range.
  • [first2, last2) is a valid range.
  • [first1, last1) is ordered in ascending order according to operator<. That is, for every pair of iterators i and j in [first1, last1) such that i precedes j, *j < *i is false.
  • [first2, last2) is ordered in ascending order according to operator<. That is, for every pair of iterators i and j in [first2, last2) such that i precedes j, *j < *i is false.
  • There is enough space to hold all of the elements being copied. More formally, the requirement is that [result, result + n) is a valid range, where n is the number of elements in the difference of the two input ranges.
  • [first1, last1) and [result, result + n) do not overlap.
  • [first2, last2) and [result, result + n) do not overlap.
For the second version:
  • [first1, last1) is a valid range.
  • [first2, last2) is a valid range.
  • [first1, last1) is ordered in ascending order according to comp. That is, for every pair of iterators i and j in [first1, last1) such that i precedes j, comp(*j, *i) is false.
  • [first2, last2) is ordered in ascending order according to comp. That is, for every pair of iterators i and j in [first2, last2) such that i precedes j, comp(*j, *i) is false.
  • There is enough space to hold all of the elements being copied. More formally, the requirement is that [result, result + n) is a valid range, where n is the number of elements in the difference of the two input ranges.
  • [first1, last1) and [result, result + n) do not overlap.
  • [first2, last2) and [result, result + n) do not overlap.

Complexity

Linear. Zero comparisons if either [first1, last1) or [first2, last2) is empty, otherwise at most 2 * ((last1 - first1) + (last2 - first2)) - 1 comparisons.

Example

inline bool lt_nocase(char c1, char c2) { return tolower(c1) < tolower(c2); }

int main()
{
  int A1[] = {1, 3, 5, 7, 9, 11};
  int A2[] = {1, 1, 2, 3, 5, 8, 13};
  char A3[] = {'a', 'b', 'b', 'B', 'B', 'f', 'g', 'h', 'H'};
  char A4[] = {'A', 'B', 'B', 'C', 'D', 'F', 'F', 'H' };

  const int N1 = sizeof(A1) / sizeof(int);
  const int N2 = sizeof(A2) / sizeof(int);
  const int N3 = sizeof(A3);
  const int N4 = sizeof(A4);

  cout << "Difference of A1 and A2: ";
  set_difference(A1, A1 + N1, A2, A2 + N2,
                 ostream_iterator<int>(cout, " "));
  cout << endl
       << "Difference of A3 and A4: ";
  set_difference(A3, A3 + N3, A4, A4 + N4,
                   ostream_iterator<char>(cout, " "),
                   lt_nocase);
  cout << endl;
}

The output is

Difference of A1 and A2: 7 9 11
Difference of A3 and A4: B B g H

Notes

[1] Even this is not a completely precise description, because the ordering by which the input ranges are sorted is permitted to be a strict weak ordering that is not a total ordering: there might be values x and y that are equivalent (that is, neither x < y nor y < x) but not equal. See the LessThan Comparable requirements for a fuller discussion. The output range consists of those elements from [first1, last1) for which equivalent elements do not exist in [first2, last2). Specifically, if the range [first1, last1) contains m elements that are equivalent to each other and the range [first2, last2) contains n elements from that equivalence class (where either m or n may be zero), then the output range contains the last max(m - n, 0) of these elements from [first1, last1). Note that this precision is only important if elements can be equivalent but not equal. If you're using a total ordering (if you're using strcmp, for example, or if you're using ordinary arithmetic comparison on integers), then you can ignore this technical distinction: for a total ordering, equality and equivalence are the same.

See also

includes, set_union, set_intersection, set_symmetric_difference, sort


set_intersection

Category: algorithms | Component type: function

Prototype

Set_intersection is an overloaded name; there are actually two set_intersection functions.
template <class InputIterator1, class InputIterator2, class OutputIterator>
OutputIterator set_intersection(InputIterator1 first1, InputIterator1 last1,
                                InputIterator2 first2, InputIterator2 last2,
                                OutputIterator result);

template <class InputIterator1, class InputIterator2, class OutputIterator,
          class StrictWeakOrdering>
OutputIterator set_intersection(InputIterator1 first1, InputIterator1 last1,
                                InputIterator2 first2, InputIterator2 last2,
                                OutputIterator result,
                                StrictWeakOrdering comp);

Description

Set_intersection constructs a sorted range that is the intersection of the sorted ranges [first1, last1) and [first2, last2). The return value is the end of the output range.

In the simplest case, set_intersection performs the "intersection" operation from set theory: the output range contains a copy of every element that is contained in both [first1, last1) and [first2, last2). The general case is more complicated, because the input ranges may contain duplicate elements. The generalization is that if a value appears m times in [first1, last1) and n times in [first2, last2) (where m or n may be zero), then it appears min(m,n) times in the output range. [1] Set_intersection is stable, meaning both that elements are copied from the first range rather than the second, and that the relative order of elements in the output range is the same as in the first input range.

The two versions of set_intersection differ in how they define whether one element is less than another. The first version compares objects using operator<, and the second compares objects using a function object comp.

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

For the first version:
  • InputIterator1 is a model of Input Iterator.
  • InputIterator2 is a model of Input Iterator.
  • OutputIterator is a model of Output Iterator.
  • InputIterator1 and InputIterator2 have the same value type.
  • InputIterator's value type is a model of LessThan Comparable.
  • The ordering on objects of InputIterator1's value type is a strict weak ordering, as defined in the LessThan Comparable requirements.
  • InputIterator's value type is convertible to a type in OutputIterator's set of value types.
For the second version:
  • InputIterator1 is a model of Input Iterator.
  • InputIterator2 is a model of Input Iterator.
  • OutputIterator is a model of Output Iterator.
  • StrictWeakOrdering is a model of Strict Weak Ordering.
  • InputIterator1 and InputIterator2 have the same value type.
  • InputIterator1's value type is convertible to StrictWeakOrdering's argument type.
  • InputIterator's value type is convertible to a type in OutputIterator's set of value types.

Preconditions

For the first version:
  • [first1, last1) is a valid range.
  • [first2, last2) is a valid range.
  • [first1, last1) is ordered in ascending order according to operator<. That is, for every pair of iterators i and j in [first1, last1) such that i precedes j, *j < *i is false.
  • [first2, last2) is ordered in ascending order according to operator<. That is, for every pair of iterators i and j in [first2, last2) such that i precedes j, *j < *i is false.
  • There is enough space to hold all of the elements being copied. More formally, the requirement is that [result, result + n) is a valid range, where n is the number of elements in the intersection of the two input ranges.
  • [first1, last1) and [result, result + n) do not overlap.
  • [first2, last2) and [result, result + n) do not overlap.
For the second version:
  • [first1, last1) is a valid range.
  • [first2, last2) is a valid range.
  • [first1, last1) is ordered in ascending order according to comp. That is, for every pair of iterators i and j in [first1, last1) such that i precedes j, comp(*j, *i) is false.
  • [first2, last2) is ordered in ascending order according to comp. That is, for every pair of iterators i and j in [first2, last2) such that i precedes j, comp(*j, *i) is false.
  • There is enough space to hold all of the elements being copied. More formally, the requirement is that [result, result + n) is a valid range, where n is the number of elements in the intersection of the two input ranges.
  • [first1, last1) and [result, result + n) do not overlap.
  • [first2, last2) and [result, result + n) do not overlap.

Complexity

Linear. Zero comparisons if either [first1, last1) or [first2, last2) is empty, otherwise at most 2 * ((last1 - first1) + (last2 - first2)) - 1 comparisons.

Example

inline bool lt_nocase(char c1, char c2) { return tolower(c1) < tolower(c2); }

int main()
{
  int A1[] = {1, 3, 5, 7, 9, 11};
  int A2[] = {1, 1, 2, 3, 5, 8, 13};
  char A3[] = {'a', 'b', 'b', 'B', 'B', 'f', 'h', 'H'};
  char A4[] = {'A', 'B', 'B', 'C', 'D', 'F', 'F', 'H' };

  const int N1 = sizeof(A1) / sizeof(int);
  const int N2 = sizeof(A2) / sizeof(int);
  const int N3 = sizeof(A3);
  const int N4 = sizeof(A4);

  cout << "Intersection of A1 and A2: ";
  set_intersection(A1, A1 + N1, A2, A2 + N2,
                   ostream_iterator<int>(cout, " "));
  cout << endl
       << "Intersection of A3 and A4: ";
  set_intersection(A3, A3 + N3, A4, A4 + N4,
                   ostream_iterator<char>(cout, " "),
                   lt_nocase);
  cout << endl;
}

The output is

Intersection of A1 and A2: 1 3 5
Intersection of A3 and A4: a b b f h

Notes

[1] Even this is not a completely precise description, because the ordering by which the input ranges are sorted is permitted to be a strict weak ordering that is not a total ordering: there might be values x and y that are equivalent (that is, neither x < y nor y < x) but not equal. See the LessThan Comparable requirements for a fuller discussion. The output range consists of those elements from [first1, last1) for which equivalent elements exist in [first2, last2). Specifically, if the range [first1, last1) contains n elements that are equivalent to each other and the range [first1, last1) contains m elements from that equivalence class (where either m or n may be zero), then the output range contains the first min(m, n) of these elements from [first1, last1). Note that this precision is only important if elements can be equivalent but not equal. If you're using a total ordering (if you're using strcmp, for example, or if you're using ordinary arithmetic comparison on integers), then you can ignore this technical distinction: for a total ordering, equality and equivalence are the same.

See also

includes, set_union, set_difference, set_symmetric_difference, sort


set_symmetric_difference

Category: algorithms | Component type: function

Prototype

Set_symmetric_difference is an overloaded name; there are actually two set_symmetric_difference functions.
template <class InputIterator1, class InputIterator2, class OutputIterator>
OutputIterator set_symmetric_difference(InputIterator1 first1,
                                        InputIterator1 last1,
                                        InputIterator2 first2,
                                        InputIterator2 last2,
                                        OutputIterator result);

template <class InputIterator1, class InputIterator2, class OutputIterator,
          class StrictWeakOrdering>
OutputIterator set_symmetric_difference(InputIterator1 first1,
                                        InputIterator1 last1,
                                        InputIterator2 first2,
                                        InputIterator2 last2,
                                        OutputIterator result,
                                        StrictWeakOrdering comp);

Description

Set_symmetric_difference constructs a sorted range that is the set symmetric difference of the sorted ranges [first1, last1) and [first2, last2). The return value is the end of the output range.

In the simplest case, set_symmetric_difference performs a set theoretic calculation: it constructs the union of the two sets A - B and B - A, where A and B are the two input ranges. That is, the output range contains a copy of every element that is contained in [first1, last1) but not [first2, last2), and a copy of every element that is contained in [first2, last2) but not [first1, last1). The general case is more complicated, because the input ranges may contain duplicate elements. The generalization is that if a value appears m times in [first1, last1) and n times in [first2, last2) (where m or n may be zero), then it appears |m-n| times in the output range. [1] Set_symmetric_difference is stable, meaning that the relative order of elements within each input range is preserved.

The two versions of set_symmetric_difference differ in how they define whether one element is less than another. The first version compares objects using operator<, and the second compares objects using a function object comp.

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

For the first version:
  • InputIterator1 is a model of Input Iterator.
  • InputIterator2 is a model of Input Iterator.
  • OutputIterator is a model of Output Iterator.
  • InputIterator1 and InputIterator2 have the same value type.
  • InputIterator's value type is a model of LessThan Comparable.
  • The ordering on objects of InputIterator1's value type is a strict weak ordering, as defined in the LessThan Comparable requirements.
  • InputIterator's value type is convertible to a type in OutputIterator's set of value types.
For the second version:
  • InputIterator1 is a model of Input Iterator.
  • InputIterator2 is a model of Input Iterator.
  • OutputIterator is a model of Output Iterator.
  • StrictWeakOrdering is a model of Strict Weak Ordering.
  • InputIterator1 and InputIterator2 have the same value type.
  • InputIterator1's value type is convertible to StrictWeakOrdering's argument type.
  • InputIterator's value type is convertible to a type in OutputIterator's set of value types.

Preconditions

For the first version:
  • [first1, last1) is a valid range.
  • [first2, last2) is a valid range.
  • [first1, last1) is ordered in ascending order according to operator<. That is, for every pair of iterators i and j in [first1, last1) such that i precedes j, *j < *i is false.
  • [first2, last2) is ordered in ascending order according to operator<. That is, for every pair of iterators i and j in [first2, last2) such that i precedes j, *j < *i is false.
  • There is enough space to hold all of the elements being copied. More formally, the requirement is that [result, result + n) is a valid range, where n is the number of elements in the symmetric difference of the two input ranges.
  • [first1, last1) and [result, result + n) do not overlap.
  • [first2, last2) and [result, result + n) do not overlap.
For the second version:
  • [first1, last1) is a valid range.
  • [first2, last2) is a valid range.
  • [first1, last1) is ordered in ascending order according to comp. That is, for every pair of iterators i and j in [first1, last1) such that i precedes j, comp(*j, *i) is false.
  • [first2, last2) is ordered in ascending order according to comp. That is, for every pair of iterators i and j in [first2, last2) such that i precedes j, comp(*j, *i) is false.
  • There is enough space to hold all of the elements being copied. More formally, the requirement is that [result, result + n) is a valid range, where n is the number of elements in the symmetric difference of the two input ranges.
  • [first1, last1) and [result, result + n) do not overlap.
  • [first2, last2) and [result, result + n) do not overlap.

Complexity

Linear. Zero comparisons if either [first1, last1) or [first2, last2) is empty, otherwise at most 2 * ((last1 - first1) + (last2 - first2)) - 1 comparisons.

Example

inline bool lt_nocase(char c1, char c2) { return tolower(c1) < tolower(c2); }

int main()
{
  int A1[] = {1, 3, 5, 7, 9, 11};
  int A2[] = {1, 1, 2, 3, 5, 8, 13};
  char A3[] = {'a', 'b', 'b', 'B', 'B', 'f', 'g', 'h', 'H'};
  char A4[] = {'A', 'B', 'B', 'C', 'D', 'F', 'F', 'H' };

  const int N1 = sizeof(A1) / sizeof(int);
  const int N2 = sizeof(A2) / sizeof(int);
  const int N3 = sizeof(A3);
  const int N4 = sizeof(A4);

  cout << "Symmetric difference of A1 and A2: ";
  set_symmetric_difference(A1, A1 + N1, A2, A2 + N2,
                           ostream_iterator<int>(cout, " "));
  cout << endl
       << "Symmetric difference of A3 and A4: ";
  set_symmetric_difference(A3, A3 + N3, A4, A4 + N4,
                           ostream_iterator<char>(cout, " "),
                           lt_nocase);
  cout << endl;
}

The output is

Symmetric difference of A1 and A2: 1 2 7 8 9 11 13
Symmetric difference of A3 and A4: B B C D F g H

Notes

[1] Even this is not a completely precise description, because the ordering by which the input ranges are sorted is permitted to be a strict weak ordering that is not a total ordering: there might be values x and y that are equivalent (that is, neither x < y nor y < x) but not equal. See the LessThan Comparable requirements for a more complete discussion. The output range consists of those elements from [first1, last1) for which equivalent elements do not exist in [first2, last2), and those elements from [first2, last2) for which equivalent elements do not exist in [first1, last1). Specifically, suppose that the range [first1, last1) contains m elements that are equivalent to each other and the range [first2, last2) contains n elements from that equivalence class (where either m or n may be zero). If m > n then the output range contains the last m - n of these elements elements from [first1, last1), and if m < n then the output range contains the last n - m of these elements elements from [first2, last2).

See also

includes, set_union, set_intersection, set_difference, sort


set_union

Category: algorithms | Component type: function

Prototype

Set_union is an overloaded name; there are actually two set_union functions.
template <class InputIterator1, class InputIterator2, class OutputIterator>
OutputIterator set_union(InputIterator1 first1, InputIterator1 last1,
                         InputIterator2 first2, InputIterator2 last2,
                         OutputIterator result);

template <class InputIterator1, class InputIterator2, class OutputIterator,
          class StrictWeakOrdering>
OutputIterator set_union(InputIterator1 first1, InputIterator1 last1,
                         InputIterator2 first2, InputIterator2 last2,
                         OutputIterator result,
                         StrictWeakOrdering comp);

Description

Set_union constructs a sorted range that is the union of the sorted ranges [first1, last1) and [first2, last2). The return value is the end of the output range.

In the simplest case, set_union performs the "union" operation from set theory: the output range contains a copy of every element that is contained in [first1, last1), [first2, last2), or both. The general case is more complicated, because the input ranges may contain duplicate elements. The generalization is that if a value appears m times in [first1, last1) and n times in [first2, last2) (where m or n may be zero), then it appears max(m,n) times in the output range. [1] Set_union is stable, meaning both that the relative order of elements within each input range is preserved, and that if an element is present in both input ranges it is copied from the first range rather than the second.

The two versions of set_union differ in how they define whether one element is less than another. The first version compares objects using operator<, and the second compares objects using a function object comp.

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

For the first version:
  • InputIterator1 is a model of Input Iterator.
  • InputIterator2 is a model of Input Iterator.
  • OutputIterator is a model of Output Iterator.
  • InputIterator1 and InputIterator2 have the same value type.
  • InputIterator's value type is a model of LessThan Comparable.
  • The ordering on objects of InputIterator1's value type is a strict weak ordering, as defined in the LessThan Comparable requirements.
  • InputIterator's value type is convertible to a type in OutputIterator's set of value types.
For the second version:
  • InputIterator1 is a model of Input Iterator.
  • InputIterator2 is a model of Input Iterator.
  • OutputIterator is a model of Output Iterator.
  • StrictWeakOrdering is a model of Strict Weak Ordering.
  • InputIterator1 and InputIterator2 have the same value type.
  • InputIterator1's value type is convertible to StrictWeakOrdering's argument type.
  • InputIterator's value type is convertible to a type in OutputIterator's set of value types.

Preconditions

For the first version:
  • [first1, last1) is a valid range.
  • [first2, last2) is a valid range.
  • [first1, last1) is ordered in ascending order according to operator<. That is, for every pair of iterators i and j in [first1, last1) such that i precedes j, *j < *i is false.
  • [first2, last2) is ordered in ascending order according to operator<. That is, for every pair of iterators i and j in [first2, last2) such that i precedes j, *j < *i is false.
  • There is enough space to hold all of the elements being copied. More formally, the requirement is that [result, result + n) is a valid range, where n is the number of elements in the union of the two input ranges.
  • [first1, last1) and [result, result + n) do not overlap.
  • [first2, last2) and [result, result + n) do not overlap.
For the second version:
  • [first1, last1) is a valid range.
  • [first2, last2) is a valid range.
  • [first1, last1) is ordered in ascending order according to comp. That is, for every pair of iterators i and j in [first1, last1) such that i precedes j, comp(*j, *i) is false.
  • [first2, last2) is ordered in ascending order according to comp. That is, for every pair of iterators i and j in [first2, last2) such that i precedes j, comp(*j, *i) is false.
  • There is enough space to hold all of the elements being copied. More formally, the requirement is that [result, result + n) is a valid range, where n is the number of elements in the union of the two input ranges.
  • [first1, last1) and [result, result + n) do not overlap.
  • [first2, last2) and [result, result + n) do not overlap.

Complexity

Linear. Zero comparisons if either [first1, last1) or [first2, last2) is empty, otherwise at most 2 * ((last1 - first1) + (last2 - first2)) - 1 comparisons.

Example

inline bool lt_nocase(char c1, char c2) { return tolower(c1) < tolower(c2); }

int main()
{
  int A1[] = {1, 3, 5, 7, 9, 11};
  int A2[] = {1, 1, 2, 3, 5, 8, 13};
  char A3[] = {'a', 'b', 'B', 'B', 'f', 'H'};
  char A4[] = {'A', 'B', 'b', 'C', 'D', 'F', 'F', 'h', 'h'};

  const int N1 = sizeof(A1) / sizeof(int);
  const int N2 = sizeof(A2) / sizeof(int);
  const int N3 = sizeof(A3);
  const int N4 = sizeof(A4);

  cout << "Union of A1 and A2: ";
  set_union(A1, A1 + N1, A2, A2 + N2,
            ostream_iterator<int>(cout, " "));
  cout << endl
       << "Union of A3 and A4: ";
  set_union(A3, A3 + N3, A4, A4 + N4,
            ostream_iterator<char>(cout, " "),
            lt_nocase);
  cout << endl;
}

The output is

Union of A1 and A2: 1 1 2 3 5 7 8 9 11 13
Union of A3 and A4: a b B B C D f F H h

Notes

[1] Even this is not a completely precise description, because the ordering by which the input ranges are sorted is permitted to be a strict weak ordering that is not a total ordering: there might be values x and y that are equivalent (that is, neither x < y nor y < x) but not equal. See the LessThan Comparable requirements for a more complete discussion. If the range [first1, last1) contains m elements that are equivalent to each other and the range [first2, last2) contains n elements from that equivalence class (where either m or n may be zero), then the output range contains max(m, n) elements from that equivalence class. Specifically, m of these elements will be copied from [first1, last1) and max(n-m, 0) of them will be copied from [first2, last2). Note that this precision is only important if elements can be equivalent but not equal. If you're using a total ordering (if you're using strcmp, for example, or if you're using ordinary arithmetic comparison on integers), then you can ignore this technical distinction: for a total ordering, equality and equivalence are the same.

See also

includes, set_intersection, set_difference, set_symmetric_difference, sort, merge


Simple Associative Container

Category: containers | Component type: concept

Description

A Simple Associative Container is an Associative Container where elements are their own keys. A key in a Simple Associative Container is not associated with any additional value.

Refinement of

Associative Container

Associated types

None, except for those described in the Associative Container requirements. Simple Associative Container, however, introduces two new type restrictions.
Key type | X::key_type | The type of the key associated with X::value_type. The types key_type and value_type must be the same type.
Iterator | X::iterator | The type of iterator used to iterate through a Simple Associative Container's elements. The types X::iterator and X::const_iterator must be the same type. That is, a Simple Associative Container does not provide mutable iterators. [1]

Notation

X | A type that is a model of Simple Associative Container
a | Object of type X
k | Object of type X::key_type
p, q | Object of type X::iterator

Definitions

Valid expressions

None, except for those defined in the Associative Container requirements.

Expression semantics

Complexity guarantees

Invariants

Immutability of Elements Every element of a Simple Associative Container is immutable. Objects may be inserted and erased, but not modified. [1]

Models

  • set
  • multiset
  • hash_set
  • hash_multiset

Notes

[1] This is a consequence of the Immutability of Keys invariant of Associative Container. Keys may never be modified; values in a Simple Associative Container are themselves keys, so it immediately follows that values in a Simple Associative Container may not be modified.

See also

Associative Container, Pair Associative Container


slist<T, Alloc>

Category: containers | Component type: type

Description

An slist is a singly linked list: a list where each element is linked to the next element, but not to the previous element. [1] That is, it is a Sequence that supports forward but not backward traversal, and (amortized) constant time insertion and removal of elements. Slists, like lists, have the important property that insertion and splicing do not invalidate iterators to list elements, and that even removal invalidates only the iterators that point to the elements that are removed. The ordering of iterators may be changed (that is, slist<T>::iterator might have a different predecessor or successor after a list operation than it did before), but the iterators themselves will not be invalidated or made to point to different elements unless that invalidation or mutation is explicit. [2]

The main difference between slist and list is that list's iterators are bidirectional iterators, while slist's iterators are forward iterators. This means that slist is less versatile than list; frequently, however, bidirectional iterators are unnecessary. You should usually use slist unless you actually need the extra functionality of list, because singly linked lists are smaller and faster than double linked lists.

Important performance note: like every other Sequence, slist defines the member functions insert and erase. Using these member functions carelessly, however, can result in disastrously slow programs. The problem is that insert's first argument is an iterator pos, and that it inserts the new element(s) before pos. This means that insert must find the iterator just before pos; this is a constant-time operation for list, since list has bidirectional iterators, but for slist it must find that iterator by traversing the list from the beginning up to pos. In other words: insert and erase are slow operations anywhere but near the beginning of the slist.

Slist provides the member functions insert_after and erase_after, which are constant time operations: you should always use insert_after and erase_after whenever possible. If you find that insert_after and erase_after aren't adequate for your needs, and that you often need to use insert and erase in the middle of the list, then you should probably use list instead of slist.

Definition

Defined in the header slist, and in the backward-compatibility header slist.h. The slist class, and the slist header, are an SGI extension; they are not part of the C++ standard.

Example

int main() {
  slist<int> L;
  L.push_front(0);
  L.push_front(1);
  L.insert_after(L.begin(), 2);
  copy(L.begin(), L.end(),        // The output is 1 2 0
       ostream_iterator<int>(cout, " "));
  cout << endl;

  slist<int>::iterator back = L.previous(L.end());
  back = L.insert_after(back, 3);
  back = L.insert_after(back, 4);
  back = L.insert_after(back, 5);
  copy(L.begin(), L.end(),        // The output is 1 2 0 3 4 5
       ostream_iterator<int>(cout, " "));
  cout << endl;
}

Template parameters

Parameter | Description | Default
T | The slist's value type: the type of object that is stored in the list. |
Alloc | The slist's allocator, used for all internal memory management. | alloc

Model of

Front Insertion Sequence

Type requirements

None, except for those imposed by the requirements of Front Insertion Sequence.

Public base classes

None.

Members

Member | Where defined | Description
value_type | Container | The type of object, T, stored in the slist.
pointer | Container | Pointer to T.
reference | Container | Reference to T
const_reference | Container | Const reference to T
size_type | Container | An unsigned integral type.
difference_type | Container | A signed integral type.
iterator | Container | Iterator used to iterate through an slist.
const_iterator | Container | Const iterator used to iterate through an slist.
iterator begin() | Container | Returns an iterator pointing to the beginning of the slist.
iterator end() | Container | Returns an iterator pointing to the end of the slist.
const_iterator begin() const | Container | Returns a const_iterator pointing to the beginning of the slist.
const_iterator end() const | Container | Returns a const_iterator pointing to the end of the slist.
size_type size() const | Container | Returns the size of the slist. Note: you should not assume that this function is constant time. It is permitted to be O(N), where N is the number of elements in the slist. If you wish to test whether an slist is empty, you should write L.empty() rather than L.size() == 0.
size_type max_size() const | Container | Returns the largest possible size of the slist.
bool empty() const | Container | true if the slist's size is 0.
slist() | Container | Creates an empty slist.
slist(size_type n) | Sequence | Creates an slist with n elements, each of which is a copy of T().
slist(size_type n, const T& t) | Sequence | Creates an slist with n copies of t.
slist(const slist&) | Container | The copy constructor.
template <class InputIterator>
slist(InputIterator f, InputIterator l)
[3]
Sequence Creates an slist with a copy of a range.
~slist() | Container | The destructor.
slist& operator=(const slist&) | Container | The assignment operator
void swap(slist&) | Container | Swaps the contents of two slists.
reference front() | Front Insertion Sequence | Returns the first element.
const_reference front() const | Front Insertion Sequence | Returns the first element.
void push_front(const T&) | Front Insertion Sequence | Inserts a new element at the beginning.
void pop_front() | Front Insertion Sequence | Removes the first element.
iterator previous(iterator pos) | slist | See below
const_iterator previous(const_iterator pos) | slist | See below
iterator insert(iterator pos, const T& x) | Sequence | Inserts x before pos.
template<class InputIterator>
void insert(iterator pos, InputIterator f, InputIterator l)
[3]
Sequence Inserts the range [first, last) before pos.
void insert(iterator pos,
            size_type n, const value_type& x)
Sequence Inserts n copies of x before pos.
iterator erase(iterator pos) | Sequence | Erases the element at position pos.
iterator erase(iterator first, iterator last) | Sequence | Erases the range [first, last)
void clear() | Sequence | Erases all of the elements.
void resize(n, t = T()) | Sequence | Inserts or erases elements at the end such that the size becomes n.
iterator insert_after(iterator pos) | slist | See below.
iterator insert_after(iterator pos, const value_type& x) | slist | See below.
template<class InputIterator>
void insert_after(iterator pos,
                  InputIterator f, InputIterator l)
slist See below.
void insert_after(iterator pos,
                  size_type n, const value_type& x)
slist See below.
iterator erase_after(iterator pos) | slist | See below.
iterator erase_after(iterator before_first, iterator last) | slist | See below.
void splice(iterator position, slist& L) | slist | See below.
void splice(iterator position, slist& L, iterator i) | slist | See below.
void splice(iterator position, slist& L, iterator f, iterator l) | slist | See below.
void splice_after(iterator pos, iterator prev) | slist | See below.
void splice_after(iterator pos,
                  iterator before_first,
                  iterator before_last)
slist See below.
void remove(const T& value) | slist | See below.
void unique() | slist | See below.
void merge(slist& L) | slist | See below.
void sort() | slist | See below.
bool operator==(const slist&,
                const slist&)
Forward Container Tests two slists for equality. This is a global function, not a member function.
bool operator<(const slist&,
               const slist&)
Forward Container Lexicographical comparison. This is a global function, not a member function.

New members

These members are not defined in the Front Insertion Sequence requirements, but are specific to slist:
Function | Description
iterator previous(iterator pos) | pos must be a valid iterator in *this. The return value is an iterator prev such that ++prev == pos. Complexity: linear in the number of iterators in the range [begin(), pos).
const_iterator previous(const_iterator pos) | pos must be a valid iterator in *this. The return value is an iterator prev such that ++prev == pos. Complexity: linear in the number of iterators in the range [begin(), pos).
iterator insert_after(iterator pos) | pos must be a dereferenceable iterator in *this. (That is, pos may not be end().) Inserts a copy of T() immediately following pos. The return value is an iterator that points to the new element. Complexity: constant time.
iterator insert_after(iterator pos,
                      const value_type& x)
pos must be a dereferenceable iterator in *this. (That is, pos may not be end().) Inserts a copy of x immediately following pos. The return value is an iterator that points to the new element. Complexity: constant time.
template<class InputIterator>
void insert_after(iterator pos,
                  InputIterator f, InputIterator l)
Inserts elements from the range [f, l) immediately following pos. Complexity: linear in last - first.
void insert_after(iterator pos,
                  size_type n, const value_type& x)
Inserts n copies of x immediately following pos. Complexity: linear in n.
iterator erase_after(iterator pos) | Erases the element pointed to by the iterator following pos. Complexity: constant time.
iterator erase_after(iterator before_first, iterator last) | Erases all elements in the range [before_first + 1, last). Complexity: linear in last - (before_first + 1).
void splice(iterator position,
            slist<T, Alloc>& x);
position must be a valid iterator in *this, and x must be an slist that is distinct from *this. (That is, it is required that &x != this.) All of the elements of x are inserted before position and removed from x. All iterators remain valid, including iterators that point to elements of x. [4] Complexity: proportional to c1 (position - begin()) + c2(x.size()), where c1 and c2 are unknown constants.

void splice(iterator position,
            slist<T, Alloc>& x,
            iterator i);
position must be a valid iterator in *this, and i must be a dereferenceable iterator in x. Splice moves the element pointed to by i from x to *this, inserting it before position. All iterators remain valid, including iterators that point to elements of x. [4] If position == i or position == ++i, this function is a null operation. Complexity: proportional to c1 (position - begin()) + c2 (i - x.begin()), where c1 and c2 are unknown constants.

void splice(iterator position,
            slist<T, Alloc>& x,
            iterator f, iterator l);
position must be a valid iterator in *this, and [first, last) must be a valid range in x. position may not be an iterator in the range [first, last). Splice moves the elements in [first, last) from x to *this, inserting them before position. All iterators remain valid, including iterators that point to elements of x. [4] Complexity: proportional to c1 (position - begin()) + c2 (f - x.begin()) + c3 (l - f), where c1, c2, and c3 are unknown constants.
void remove(const T& val); | Removes all elements that compare equal to val. The relative order of elements that are not removed is unchanged, and iterators to elements that are not removed remain valid. This function is linear time: it performs exactly size() comparisons for equality.
void splice_after(iterator pos, iterator prev) | pos must be a dereferenceable iterator in *this, and prev must be a dereferenceable iterator either in *this or in some other slist. (Note: "dereferenceable iterator" implies that neither pos nor prev may be an off-the-end iterator.) Moves the element following prev to *this, inserting it immediately after pos. Complexity: constant time.
void splice_after(iterator pos,
                  iterator before_first,
                  iterator before_last)
pos must be a dereferenceable iterator in *this, and before_first and before_last must be dereferenceable iterators either in *this or in some other slist. (Note: "dereferenceable iterator" implies that none of these iterators may be off-the-end iterators.) Moves the elements in the range [before_first + 1, before_last + 1) to *this, inserting them immediately after pos. Complexity: constant time.
template<class Predicate>
void remove_if(Predicate p);
[5]
Removes all elements *i such that p(*i) is true. The relative order of elements that are not removed is unchanged, and iterators to elements that are not removed remain valid. This function is linear time: it performs exactly size() applications of p.
void unique(); | Removes all but the first element in every consecutive group of equal elements. The relative order of elements that are not removed is unchanged, and iterators to elements that are not removed remain valid. This function is linear time: it performs exactly size() - 1 comparisons for equality.
template<class BinaryPredicate>
void unique(BinaryPredicate p);
[5]
Removes all but the first element in every consecutive group of equivalent elements, where two elements *i and *j are considered equivalent if p(*i, *j) is true. The relative order of elements that are not removed is unchanged, and iterators to elements that are not removed remain valid. This function is linear time: it performs exactly size() - 1 comparisons for equality.
void merge(slist<T, Alloc>& x); | Both *this and x must be sorted according to operator<, and they must be distinct. (That is, it is required that &x != this.) This function removes all of x's elements and inserts them in order into *this. The merge is stable; that is, if an element from *this is equivalent to one from x, then the element from *this will precede the one from x. All iterators to elements in *this and x remain valid. This function is linear time: it performs at most size() + x.size() - 1 comparisons.
template<class BinaryPredicate>
void merge(slist<T, Alloc>& x,
           BinaryPredicate Comp);
[5]
Comp must be a comparison function that induces a strict weak ordering (as defined in the LessThan Comparable requirements) on objects of type T, and both *this and x must be sorted according to that ordering. The slists x and *this must be distinct. (That is, it is required that &x != this.) This function removes all of x's elements and inserts them in order into *this. The merge is stable; that is, if an element from *this is equivalent to one from x, then the element from *this will precede the one from x. All iterators to elements in *this and x remain valid. This function is linear time: it performs at most size() + x.size() - 1 applications of Comp.
void reverse(); | Reverses the order of elements in the slist. All iterators remain valid and continue to point to the same elements. [6] This function is linear time.
void sort(); | Sorts *this according to operator<. The sort is stable, that is, the relative order of equivalent elements is preserved. All iterators remain valid and continue to point to the same elements. [7] The number of comparisons is approximately N log N, where N is the slist's size.
template<class BinaryPredicate>
void sort(BinaryPredicate comp);
[5]
Comp must be a comparison function that induces a strict weak ordering (as defined in the LessThan Comparable requirements) on objects of type T. This function sorts the slist *this according to Comp. The sort is stable, that is, the relative order of equivalent elements is preserved. All iterators remain valid and continue to point to the same elements. [7] The number of comparisons is approximately N log N, where N is the slist's size.

Notes

[1] The lists in such languages as Common Lisp, Scheme, and ML are singly linked lists. In some programming languages, almost all data structures are represented as singly linked lists.

[2] A comparison with vector is instructive. Suppose that i is a valid vector<T>::iterator. If an element is inserted or removed in a position that precedes i, then this operation will either result in i pointing to a different element than it did before, or else it will invalidate i entirely. (A vector<T>::iterator will be invalidated, for example, if an insertion requires a reallocation.) However, suppose that i and j are both iterators into a vector, and there exists some integer n such that i == j + n. In that case, even if elements are inserted into the vector and i and j point to different elements, the relation between the two iterators will still hold. An slist is exactly the opposite: iterators will not be invalidated, and will not be made to point to different elements, but, for slist iterators, the predecessor/successor relationship is not invariant.

[3] This member function relies on member template functions, which at present (early 1998) are not supported by all compilers. If your compiler supports member templates, you can call this function with any type of input iterator. If your compiler does not yet support member templates, though, then the arguments must either be of type const value_type* or of type slist::const_iterator.

[4] A similar property holds for all versions of insert() and erase(). Slist<T, Alloc>::insert() never invalidates any iterators, and slist<T, Alloc>::erase() only invalidates iterators pointing to the elements that are actually being erased.

[5] This member function relies on member template functions, which at present (early 1998) are not supported by all compilers. You can only use this member function if your compiler supports member templates.

[6] The reverse algorithm works only for bidirectional iterators. Even if reverse were extended to work with forward iterators, however, it would still be useful to have the reverse member function: it has different iterator invalidation semantics. That is, the reverse member function preserves the value that each iterator points to. Note also that the algorithm reverse(L.begin(), L.end()) uses T's assignment operator, but the member function L.reverse() does not.

[7] The sort algorithm works only for random access iterators. In principle, however, it would be possible to write a sort algorithm that also accepted forward iterators. Even if there were such a version of sort, it would still be useful for slist to have a sort member function. That is, sort is provided as a member function not only for the sake of efficiency, but also because of the property that it preserves the values that list iterators point to.

See also

Bidirectional Iterator, Reversible Container, Sequence, list, vector


sort

Category: algorithms | Component type: function

Prototype

Sort is an overloaded name; there are actually two sort functions.
template <class RandomAccessIterator>
void sort(RandomAccessIterator first, RandomAccessIterator last);

template <class RandomAccessIterator, class StrictWeakOrdering>
void sort(RandomAccessIterator first, RandomAccessIterator last,
          StrictWeakOrdering comp);

Description

Sort sorts the elements in [first, last) into ascending order, meaning that if i and j are any two valid iterators in [first, last) such that i precedes j, then *j is not less than *i. Note: sort is not guaranteed to be stable. That is, suppose that *i and *j are equivalent: neither one is less than the other. It is not guaranteed that the relative order of these two elements will be preserved by sort. [1]

The two versions of sort differ in how they define whether one element is less than another. The first version compares objects using operator<, and the second compares objects using a function object comp.

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

For the first version, the one that takes two arguments:
  • RandomAccessIterator is a model of Random Access Iterator.
  • RandomAccessIterator is mutable.
  • RandomAccessIterator's value type is LessThan Comparable.
  • The ordering relation on RandomAccessIterator's value type is a strict weak ordering, as defined in the LessThan Comparable requirements.
For the second version, the one that takes three arguments:
  • RandomAccessIterator is a model of Random Access Iterator.
  • RandomAccessIterator is mutable.
  • StrictWeakOrdering is a model of Strict Weak Ordering.
  • RandomAccessIterator's value type is convertible to StrictWeakOrdering's argument type.

Preconditions

  • [first, last) is a valid range.

Complexity

O(N log(N)) comparisons (both average and worst-case), where N is last - first. [2]

Example

int A[] = {1, 4, 2, 8, 5, 7};
const int N = sizeof(A) / sizeof(int);
sort(A, A + N);
copy(A, A + N, ostream_iterator<int>(cout, " "));
// The output is " 1 2 4 5 7 8".

Notes

[1] Stable sorting is sometimes important if you are sorting records that have multiple fields: you might, for example, want to sort a list of people by first name and then by last name. The algorithm stable_sort does guarantee to preserve the relative ordering of equivalent elements.

[2] Earlier versions of sort used the quicksort algorithm (C. A. R. Hoare, Comp. J. 5, 1962), using a pivot chosen by median of three (R. C. Singleton, CACM 12, 1969). Quicksort has O(N log(N)) average complexity, but quadratic worst-case complexity. See section 5.2.2 of Knuth for a discussion. (D. E. Knuth, The Art of Computer Programming. Volume 3: Sorting and Searching. Addison-Wesley, 1975.) The current implementation of sort, however, uses the introsort algorithm (D. R. Musser, "Introspective Sorting and Selection Algorithms", Software Practice and Experience 27(8):983, 1997.) whose worst case complexity is O(N log(N)). Introsort is very similar to median-of-three quicksort, and is at least as fast as quicksort on average.

See also

stable_sort, partial_sort, partial_sort_copy, sort_heap, is_sorted, binary_search, lower_bound, upper_bound, less<T>, StrictWeakOrdering, LessThan Comparable


Sorted Associative Container

Category: containers | Component type: concept

Description

A Sorted Associative Container is a type of Associative Container. Sorted Associative Containers use an ordering relation on their keys; two keys are considered to be equivalent if neither one is less than the other. (If the ordering relation is case-insensitive string comparison, for example, then the keys "abcde" and "aBcDe" are equivalent.)

Sorted Associative Containers guarantee that the complexity for most operations is never worse than logarithmic [1], and they also guarantee that their elements are always sorted in ascending order by key.

Refinement of

Reversible Container, Associative Container

Associated types

Two new types are introduced, in addition to the types defined in the Associative Container and Reversible Container requirements.
X::key_compare | The type of a Strict Weak Ordering used to compare keys. Its argument type must be X::key_type.
X::value_compare | The type of a Strict Weak Ordering used to compare values. Its argument type must be X::value_type, and it compares two objects of value_type by passing the keys associated with those objects to a function object of type key_compare.

Notation

X | A type that is a model of Sorted Associative Container
a | Object of type X
t | Object of type X::value_type
k | Object of type X::key_type
p, q | Object of type X::iterator
c | Object of type X::key_compare

Definitions

Valid expressions

In addition to the expressions defined in Associative Container and Reversible Container, the following expressions must be valid.
Name | Expression | Type requirements | Return type
Default constructor
X()
X a;
Constructor with compare
X(c)
X a(c);
Key comparison | a.key_comp() | X::key_compare
Value comparison | a::value_compare() | X::value_compare
Lower bound | a.lower_bound(k) | iterator if a is mutable, otherwise const_iterator.
Upper bound | a.upper_bound(k) | iterator if a is mutable, otherwise const_iterator.
Equal range | a.equal_range(k) | pair<iterator, iterator> if a is mutable, otherwise pair<const_iterator, const_iterator>.

Expression semantics

Name | Expression | Precondition | Semantics | Postcondition
Default constructor
X()
X a;
Creates an empty container, using key_compare() as the comparison object. The size of the container is 0.
Constructor with compare
X(c)
X a(c);
Creates an empty container, using c as the comparison object. The size of the container is 0. key_comp() returns a function object that is equivalent to c.
Key comparison | a.key_comp() | Returns the key comparison object used by a.
Value comparison | a::value_compare() | Returns the value comparison object used by a. | If t1 and t2 are objects of type value_type, and k1 and k2 are the keys associated with them, then a.value_comp()(t1, t2) is equivalent to a.key_comp()(k1, k2).
Lower bound | a.lower_bound(k) | Returns an iterator pointing to the first element whose key is not less than k. Returns a.end() if no such element exists. | If a contains any elements that have the same key as k, then the return value of lower_bound points to the first such element.
Upper bound | a.upper_bound(k) | Returns an iterator pointing to the first element whose key is greater than k. Returns a.end() if no such element exists. | If a contains any elements that have the same key as k, then the return value of upper_bound points to one past the last such element.
Equal range | a.equal_range(k) | Returns a pair whose first element is a.lower_bound(k) and whose second element is a.upper_bound(k).

Complexity guarantees

key_comp() and value_comp() are constant time.

Erase element is constant time.

Erase key is O(log(size()) + count(k)). [1]

Erase range is O(log(size()) + N), where N is the length of the range. [1]

Find is logarithmic. [1]

Count is O(log(size()) + count(k)). [1]

Lower bound, upper bound, and equal range are logarithmic. [1]

Invariants

Definition of value_comp | If t1 and t2 are objects of type X::value_type and k1 and k2 are the keys associated with those objects, then a.value_comp() returns a function object such that a.value_comp()(t1, t2) is equivalent to a.key_comp()(k1, k2).
Ascending order | The elements in a Sorted Associative Container are always arranged in ascending order by key. That is, if a is a Sorted Associative Container, then is_sorted(a.begin(), a.end(), a.value_comp()) is always true.

Models

  • set
  • multiset
  • map
  • multimap

Notes

[1] This is a much stronger guarantee than the one provided by Associative Container. The guarantees in Associative Container only apply to average complexity; worst case complexity is allowed to be greater. Sorted Associative Container, however, provides an upper limit on worst case complexity.

[2] This definition is consistent with the semantics described in Associative Container. It is a stronger condition, though: if a contains no elements with the key k, then a.equal_range(k) returns an empty range that indicates the position where those elements would be if they did exist. The Associative Container requirements, however, merely state that the return value is an arbitrary empty range.

See also

Associative Container, Hashed Associative Container


sort_heap

Category: algorithms | Component type: function

Prototype

Sort_heap is an overloaded name; there are actually two sort_heap functions.
template <class RandomAccessIterator>
void sort_heap(RandomAccessIterator first, RandomAccessIterator last);

template <class RandomAccessIterator, class StrictWeakOrdering>
void sort_heap(RandomAccessIterator first, RandomAccessIterator last,
               StrictWeakOrdering comp);

Description

Sort_heap turns a heap [1] [first, last) into a sorted range. Note that this is not a stable sort: the relative order of equivalent elements is not guaranteed to be preserved.

The two versions of sort_heap differ in how they define whether one element is less than another. The first version compares objects using operator<, and the second compares objects using a function object comp.

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

For the first version, the one that takes two arguments:
  • RandomAccessIterator is a model of Random Access Iterator.
  • RandomAccessIterator is mutable.
  • RandomAccessIterator's value type is a model of LessThan Comparable.
  • The ordering on objects of RandomAccessIterator's value type is a strict weak ordering, as defined in the LessThan Comparable requirements.
For the second version, the one that takes three arguments:
  • RandomAccessIterator is a model of Random Access Iterator.
  • RandomAccessIterator is mutable.
  • StrictWeakOrdering is a model of Strict Weak Ordering.
  • RandomAccessIterator's value type is convertible to StrictWeakOrdering's argument type.

Preconditions

For the first version, the one that takes two arguments:
  • [first, last) is a valid range.
  • [first, last) is a heap. That is, is_heap(first, last) is true.
For the second version, the one that takes three arguments:
  • [first, last) is a valid range.
  • [first, last) is a heap. That is, is_heap(first, last, comp) is true.

Complexity

At most N * log(N) comparisons, where N is last - first.

Example

int main()
{
  int A[] = {1, 4, 2, 8, 5, 7};
  const int N = sizeof(A) / sizeof(int);

  make_heap(A, A+N);
  copy(A, A+N, ostream_iterator<int>(cout, " "));
  cout << endl;

  sort_heap(A, A+N);
  copy(A, A+N, ostream_iterator<int>(cout, " "));
  cout << endl;
}

Notes

[1] A heap is a particular way of ordering the elements in a range of Random Access Iterators [f, l). The reason heaps are useful (especially for sorting, or as priority queues) is that they satisfy two important properties. First, *f is the largest element in the heap. Second, it is possible to add an element to a heap (using push_heap), or to remove *f, in logarithmic time. Internally, a heap is a tree represented as a sequential range. The tree is constructed so that that each node is less than or equal to its parent node.

See also

push_heap, pop_heap, make_heap, is_heap, sort, stable_sort, partial_sort, partial_sort_copy


stable_partition

Category: algorithms | Component type: function

Prototype

template <class ForwardIterator, class Predicate>
ForwardIterator stable_partition(ForwardIterator first, ForwardIterator last,
                                 Predicate pred);

Description

Stable_partition is much like partition: it reorders the elements in the range [first, last) based on the function object pred, such that all of the elements that satisfy pred appear before all of the elements that fail to satisfy it. The postcondition is that, for some iterator middle in the range [first, last), pred(*i) is true for every iterator i in the range [first, middle) and false for every iterator i in the range [middle, last). The return value of stable_partition is middle.

Stable_partition differs from partition in that stable_partition is guaranteed to preserve relative order. That is, if x and y are elements in [first, last) such that pred(x) == pred(y), and if x precedes y, then it will still be true after stable_partition is true that x precedes y. [1]

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

  • ForwardIterator is a model of Forward Iterator
  • Predicate is a model of Predicate
  • ForwardIterator's value type is convertible to Predicate's argument type.

Preconditions

  • [first, last) is a valid range.

Complexity

Stable_partition is an adaptive algorithm: it attempts to allocate a temporary memory buffer, and its run-time complexity depends on how much memory is available. Worst-case behavior (if no auxiliary memory is available) is at most N*log(N) swaps, where N is last - first, and best case (if a large enough auxiliary memory buffer is available) is linear in N. In either case, pred is applied exactly N times.

Example

Reorder a sequence so that even numbers precede odd numbers.
int A[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
const int N = sizeof(A)/sizeof(int);
stable_partition(A, A + N,
                 compose1(bind2nd(equal_to<int>(), 0),
                          bind2nd(modulus<int>(), 2)));
copy(A, A + N, ostream_iterator<int>(cout, " "));
// The output is "2 4 6 8 10 1 3 5 7 9". [1]

Notes

[1] Note that the complexity of stable_partition is greater than that of partition: the guarantee that relative order will be preserved has a significant runtime cost. If this guarantee isn't important to you, you should use partition.

See also

partition, Predicate, function object


stable_sort

Category: algorithms | Component type: function

Prototype

Stable_sort is an overloaded name; there are actually two stable_sort functions.
template <class RandomAccessIterator>
void stable_sort(RandomAccessIterator first, RandomAccessIterator last);

template <class RandomAccessIterator, class StrictWeakOrdering>
void stable_sort(RandomAccessIterator first, RandomAccessIterator last,
                 StrictWeakOrdering comp);

Description

Stable_sort is much like sort: it sorts the elements in [first, last) into ascending order, meaning that if i and j are any two valid iterators in [first, last) such that i precedes j, then *j is not less than *i. Stable_sort differs from sort in two ways. First, stable_sort uses an algorithm that has different run-time complexity than sort. Second, as the name suggests, stable_sort is stable: it preserves the relative ordering of equivalent elements. That is, if x and y are elements in [first, last) such that x precedes y, and if the two elements are equivalent (neither x < y nor y < x) then a postcondition of stable_sort is that x still precedes y. [1]

The two versions of stable_sort differ in how they define whether one element is less than another. The first version compares objects using operator<, and the second compares objects using a function object comp.

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

For the first version, the one that takes two arguments:
  • RandomAccessIterator is a model of Random Access Iterator.
  • RandomAccessIterator is mutable.
  • RandomAccessIterator's value type is LessThan Comparable.
  • The ordering relation on RandomAccessIterator's value type is a strict weak ordering, as defined in the LessThan Comparable requirements.
For the second version, the one that takes three arguments:
  • RandomAccessIterator is a model of Random Access Iterator.
  • RandomAccessIterator is mutable.
  • StrictWeakOrdering is a model of Strict Weak Ordering.
  • RandomAccessIterator's value type is convertible to StrictWeakOrdering's argument type.

Preconditions

  • [first, last) is a valid range.

Complexity

Stable_sort is an adaptive algorithm: it attempts to allocate a temporary memory buffer, and its run-time complexity depends on how much memory is available. Worst-case behavior (if no auxiliary memory is available) is N (log N)^2 comparisons, where N is last - first, and best case (if a large enough auxiliary memory buffer is available) is N (log N). [2]

Example

Sort a sequence of characters, ignoring their case. Note that the relative order of characters that differ only by case is preserved.
inline bool lt_nocase(char c1, char c2) { return tolower(c1) < tolower(c2); }

int main()
{
  char A[] = "fdBeACFDbEac";
  const int N = sizeof(A) - 1;
  stable_sort(A, A+N, lt_nocase);
  printf("%s\n", A);
  // The printed result is ""AaBbCcdDeEfF".
}

Notes

[1] Note that two elements may be equivalent without being equal. One standard example is sorting a sequence of names by last name: if two people have the same last name but different first names, then they are equivalent but not equal. This is why stable_sort is sometimes useful: if you are sorting a sequence of records that have several different fields, then you may want to sort it by one field without completely destroying the ordering that you previously obtained from sorting it by a different field. You might, for example, sort by first name and then do a stable sort by last name.

[2] Stable_sort uses the merge sort algorithm; see section 5.2.4 of Knuth. (D. E. Knuth, The Art of Computer Programming. Volume 3: Sorting and Searching. Addison-Wesley, 1975.)

See also

sort, partial_sort, partial_sort_copy, binary_search, lower_bound, upper_bound, less<T>, StrictWeakOrdering, LessThan Comparable


stack<T, Sequence>

Categories: containers, adaptors | Component type: type

Description

A stack is an adaptor that provides a restricted subset of Container functionality: it provides insertion, removal, and inspection of the element at the top of the stack. Stack is a "last in first out" (LIFO) data structure: the element at the top of a stack is the one that was most recently added. [1] Stack does not allow iteration through its elements. [2]

Stack is a container adaptor, meaning that it is implemented on top of some underlying container type. By default that underlying type is deque, but a different type may be selected explicitly.

Example

int main() {
  stack<int> S;
  S.push(8);
  S.push(7);
  S.push(4);
  assert(S.size() == 3);

  assert(S.top() == 4);
  S.pop();

  assert(S.top() == 7);
  S.pop();

  assert(S.top() == 8);
  S.pop();

  assert(S.empty());
}

Definition

Defined in the standard header stack, and in the nonstandard backward-compatibility header stack.h.

Template parameters

Parameter | Description | Default
T | The type of object stored in the stack. |
Sequence | The type of the underlying container used to implement the stack. | deque<T>

Model of

Assignable, Default Constructible

Type requirements

  • T is a model of Assignable.
  • Sequence is a model of Back Insertion Sequence.
  • Sequence::value_type is the same type as T.
  • If operator== is used, then T is a model of Equality Comparable
  • If operator< is used, then T is a model of LessThan Comparable.

Public base classes

None.

Members

Member | Where defined | Description
value_type | stack | See below.
size_type | stack | See below.
stack() | Default Constructible | The default constructor. Creates an empty stack.
stack(const stack&) | Assignable | The copy constructor.
stack& operator=(const stack&) | Assignable | The assignment operator.
bool empty() const | stack | See below.
size_type size() const | stack | See below.
value_type& top() | stack | See below.
const value_type& top() const | stack | See below.
void push(const value_type&) | stack | See below.
void pop() [3] | stack | See below.
bool operator==(const stack&, const stack&) | stack | See below.
bool operator<(const stack&, const stack&) | stack | See below.

New members

These members are not defined in the Assignable and Default Constructible requirements, but are specific to stack.
Member | Description
value_type | The type of object stored in the stack. This is the same as T and Sequence::value_type.
size_type | An unsigned integral type. This is the same as Sequence::size_type.
bool empty() const | Returns true if the stack contains no elements, and false otherwise. S.empty() is equivalent to S.size() == 0.
size_type size() const | Returns the number of elements contained in the stack.
value_type& top() | Returns a mutable reference to the element at the top of the stack. Precondition: empty() is false.
const value_type& top() const | Returns a const reference to the element at the top of the stack. Precondition: empty() is false.
void push(const value_type& x) | Inserts x at the top of the stack. Postconditions: size() will be incremented by 1, and top() will be equal to x.
void pop() | Removes the element at the top of the stack. [3] Precondition: empty() is false. Postcondition: size() will be decremented by 1.
bool operator==(const stack&, const stack&) | Compares two stacks for equality. Two stacks are equal if they contain the same number of elements and if they are equal element-by-element. This is a global function, not a member function.
bool operator<(const stack&, const stack&) | Lexicographical ordering of two stacks. This is a global function, not a member function.

Notes

[1] Stacks are a standard data structure, and are discussed in all algorithm books. See, for example, section 2.2.1 of Knuth. (D. E. Knuth, The Art of Computer Programming. Volume 1: Fundamental Algorithms, second edition. Addison-Wesley, 1973.)

[2] This restriction is the only reason for stack to exist at all. Note that any Front Insertion Sequence or Back Insertion Sequence can be used as a stack; in the case of vector, for example, the stack operations are the member functions back, push_back, and pop_back. The only reason to use the container adaptor stack instead is to make it clear that you are performing only stack operations, and no other operations.

[3] One might wonder why pop() returns void, instead of value_type. That is, why must one use top() and pop() to examine and remove the top element, instead of combining the two in a single member function? In fact, there is a good reason for this design. If pop() returned the top element, it would have to return by value rather than by reference: return by reference would create a dangling pointer. Return by value, however, is inefficient: it involves at least one redundant copy constructor call. Since it is impossible for pop() to return a value in such a way as to be both efficient and correct, it is more sensible for it to return no value at all and to require clients to use top() to inspect the value at the top of the stack.

See also

queue, priority_queue, Container, Sequence


C++ I/O library (experimental)

This is an experimental snapshot of SGI's standard C++ library. You should download it if you are interested in contributing to an ongoing development effort, but not (yet) if you are looking for a library implementation that is guaranteed to work "out of the box".

This snapshot includes the entire standard C++ library: STL, iostream/locale, and numerics (valarray and complex). It does not include a standard C library implementation; it is intended to interoperate with an existing C library.

Please note that some aspects of an I/O library are inherently platform-specific. (See below for more details.) This library has been tested on IRIX 6.x using the SGI MIPSpro 7.3 compiler, and on Linux, using glibc 2.0 and the egcs 1.1.2 compilers. It passes simple tests on Microsoft Windows NT using the Microsoft Visual C++ 6.0 compiler (with Service Pack 3). Compiling it on other platforms will almost certainly require at least some work. Porting to another version of Unix, using a relatively recent C++ compiler, should not be difficult.

We welcome suggestions, patches, and bug fixes. Please send comments to stl@sgi.com.

Some notes on the structure of the I/O library

  • It shares some files, such as char_traits.h, with our STL. These snapshots include the full STL distribution as well as the iostreams implementation, since it's hard to draw a line between these two parts of the standard C++ library.

  • Certain parts of the STL depend on the I/O library, and they behave differently depending on whether they use "classic" AT&T cfront iostreams or a standard-conforming I/O implementation with templatized iostreams. To use the new iostreams library you must tell the compiler where to find the headers, add the I/O library to the link line, and tell the STL that it should use standard-conforming iostreams. A compilation line may look something like this:
        g++  -I.  -D__STL_USE_NEW_IOSTREAMS -g hello.cxx libCio.a
    Alternatively, you can edit the stl_config.h header so that the macro __STL_USE_NEW_IOSTREAMS gets defined automatically.

  • Locales are a tricky point. It is impossible to layer C++ locales on top of the C library locales. The problem is that the standard C library only has one active locale at a time, as determined by the global setlocale function. In C++, though, locales are objects, and there can be any number of active locales at the same time. In a single-threaded world it would be possible (although horribly inefficient) to implement this with setlocale, but there's no safe way to do that in a multithreaded environment.

    This iostream/locale library is intended to coexist with a preexisting C library. It assumes that for any C library implementation there is some way---just not a portable way---to get at the underlying data files so that we can have multiple active locales. We defined an interface, found in in c_locale.h, for this functionality. Our C++ I/O library requires some implementation for the c_locale.h interface. We believe that implementing the c_locale.h interface is the major work involved in porting the I/O library to a new platform.

    We have implemented the c_locale interface for the IRIX C library (it is not included here because it includes code that, for legal reasons, SGI can't release as open source), and for the GNU glibc 2.x library.

    Additionally, we provide a stub implementation of the c_locale interface. This interface is used only for named locales that the OS knows about, such as (in IRIX) "de", "es_MX", and "fr_BE". It isn't used for user-defined locales, or for the classic locale. So the stub implementation takes any string, and returns a failure indication when the user attempts to create a named locale. That's perfectly conforming, according to the C++ standard, and it's even useful. (At least for people who don't have a pressing need for internationalization.) This can serve as a stopgap for platforms where we don't yet have a real c_locale implementation.

  • There are a couple of smaller places where we have system-dependent code. One, of course, is in basic_filebuf (see especially fstream.cxx), which makes system calls for reading and writing. (On Unix, it uses such system calls as open, close, read, write, fcntl, lseek, mmap, and munmap.)

    We have tried to abstract out as much system-dependent stuff as possible into the _Filebuf_base class. At present it supports IRIX and Linux; porting to other versions of Unix should be easy. There is also some incomplete support for NT; issues there include the '\n' <-> CRLF translation in text mode, and the use of native Win32 system calls, especially for memory mapped I/O.

  • Another place where we've got system dependent code is syncing with stdio. The C++ standard requires that there be a mode in which iostreams and stdio are synchronized (the C++ standard is imprecise about just what synchronization means, but, after talking to the people who wrote that part of the standard, it's clear that it means a very close coupling), and it requires that synchronized mode be the default. We could have satisfied this requirement by implementing things in terms of putc and getc, but that would have been horribly inefficient. Instead we did something uglier, but more efficient: we directly manipulate the pointers inside a FILE object. We've encapsulated knowledge of struct FILE into the header <stl_stdio_file.h>, which defines a few inline functions for this manipulation. Again, this header has to be modified for every OS that we target. This has not proven to be a serious problem in practice, since most stdio implementations appear to be very similar to each other.

    (An aside: the C++ standard does not say what type of streambuf is used by the standard streams, cin, cout, cerr, etc. Our choice: the wide streams, and in unsynchronized mode the narrow streams as well, use basic_filebuf. In synchronized mode the narrow streams instead use SGI::stdio_istreambuf or SGI::stdio_ostreambuf. Those classes are defined in the header <stdio_streambuf>, and, of course, they are extensions.)

  • Initialization of iostreams is tricky. The standard specifies how it's supposed to work in some detail, and it doesn't seem to be possible to do it portably. Our solution, which is admittedly a ghastly hack, is in iostream.cxx. It's nonportable, but it will work on many platforms. On some platforms there are better ways of doing this.

Areas that need more work

  • Portability to other platforms
    • Workarounds for compilers that don't support the full C++ language
    • Writing a low-level locale implementation for other C libraries.
    • Use native file I/O system calls for non-Unix operating systems.
    • Testing on other configurations
  • The basic_fstream class sometimes uses memory-mapped I/O for file input. It should also use memory-mapped I/O for output when possible.
  • Testing of nontrivial code conversions from wide to narrow characters, especially with variable-width and state-dependent encodings, has been sporadic; it's likely that there are still bugs in this area. Most of the relevant code is in <fstream>.
  • The numeric input facets handle istreambuf_iterator naively. They should look directly at the buffer inside the streambuf, rather than using sgetc, sbumpc, and snextc to get one character at a time. (See the header <istream> for an example of how this can be done.) The same optimization applies to the time and monetary facets, but they're less important.
  • There has been some performance tuning for better execution speed, but there has been very little performance tuning for code size or compilation speed.

Snapshots

June 8, 2000 | stdlib_20000608.tar.gz stdlib_20000608.zip | Many small bug fixes and compatibility patches. Change to the low-level locale API to improve handling of locale "", which indicates that we are to use a locale that corresponds to the user's preference. (The major changes are in c_locale.h and locale.cxx.) This change is probably a performance improvement in the common case.
May 5, 2000 | stdlib_20000505.tar.gz stdlib_20000505.zip | Changed deque to remove the extension of a third, default template parameter by which the user can control the node size. The extension does not appear to be standard-conforming.
April 18, 2000 | stdlib_20000418.tar.gz stdlib_20000418.zip | Changed basic_istream::seekg and basic_ostream::seekp so that they conform to the resolution to library issue 136 adopted in Tokyo. (seekg should set only the get pointer, and seekp should set only get put pointer.) Fixed a bug that affects string output when the width is nonzero; thanks to Volker H. Simonis for a bug report and patch. Changed bitset to remove the extension of a second template parameter. The extension does not appear to be standard-conforming (see library issue 94), and it isn't very useful anyway.
April 14, 2000 | stdlib_20000414.tar.gz stdlib_20000414.zip | Small bug fixes. Thanks to Alain Miniussi for patches to satisfy compiler that perform certain strict error checks, and to Boris Fomitchev for a Sun compatibility patch.
April 3, 2000 | stdlib_20000403.tar.gz stdlib_20000403.zip | Numeric I/O bug fixes. Thanks to Dave Abrahams for a hex input patch.
March 28, 2000 | stdlib_20000328.tar.gz stdlib_20000328.zip | Various bug fixes. Thanks to Kevin Shepherd for Sun and Win32 patches, and Dan Tsafrir for a g++ 2.91 patch.
March 21, 2000 | stdlib_20000321.tar.gz stdlib_20000321.zip | Various bug fixes, including workarounds for Microsoft C++ 5.0 limitations. Thanks to Jan Mikkelsen for changes for Intel C++ compatibility patches, and Jochen Schlick for UnixWare 7 compatibility patches.
February 18, 2000 | stdlib_20000218.tar.gz stdlib_20000218.zip | Fixed another native Win32 API problem; thanks again to Kevin Shepherd. Algorithmic improvement to make list<>::reverse() smaller and faster; thanks to John D. Valois.
January 28, 2000 | stdlib_20000128.tar.gz stdlib_20000128.zip | Fixed a memory leak in basic_filebuf. Fixed another native Win32 API problem; thanks again to Kevin Shepherd and Boris Fomitchev.
January 25, 2000 | stdlib_20000125.tar.gz stdlib_20000125.zip | Bug fixes. Thanks to Kevin Shepherd and Boris Fomitchev for patches that fix a Win32 initialization problem.
January 10, 2000 | stdlib_20000110.tar.gz stdlib_20000110.zip | The Win32 version of this library now uses the native Win32 API, rather than Unix emulation. Thanks to Kevin Shepherd for the patch to support native Win32 calls.
January 7, 2000 | stdlib_20000107.tar.gz stdlib_20000107.zip | More bug fixes and compatibility improvements. Thanks to Jan Mikkelsen for an Intel C++ compatibility patch.
December 28, 1999 | stdlib_19991228.tar.gz stdlib_19991228.zip | Minor bug fixes. Thanks to Vadim Egorov for a time facets patch.
December 15, 1999 | stdlib_19991215.tar.gz stdlib_19991215.zip | Changes for Microsoft compatibility. Library now passes more complete test suite using Visual C++ 6.0 SP3.
December 10, 1999 | stdlib_19991210.tar.gz stdlib_19991210.zip | More small bug fixes.
November 23, 1999 | stdlib_19991123.tar.gz stdlib_19991123.zip | Minor bug fixes and performance improvements. Makefile is now provided for Microsoft C++ and for IRIX.
October 14, 1999 | stdlib_19991014.tar.gz stdlib_19991014.zip | Library now compiles and passes simple tests using Microsoft Visual C++ 6.0 (with Service Pack 3).
September 5, 1999 | stdlib_19990905.tar.gz stdlib_19990905.zip | Library now includes support for class complex.
August 30, 1999 | stdlib_19990830.tar.gz stdlib_19990830.zip |
The C++ I/O library is released under the same terms as the SGI STL.

Copyright © 1999
Silicon Graphics Computer Systems, Inc.

Permission to use, copy, modify, distribute and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation. Silicon Graphics makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty.


Index: The Standard Template Library

accumulate
Adaptable Binary Function
Adaptable Binary Predicate
Adaptable Generator
Adaptable Predicate
Adaptable Unary Function
adjacent_difference
adjacent_find
advance
Allocators
Assignable
Associative Container
Back Insertion Sequence
back_insert_iterator<BackInsertionSequence>
basic_string<charT, traits, Alloc>
Bidirectional Iterator
bidirectional_iterator<T, Distance>
bidirectional_iterator_tag
Binary Function
Binary Predicate
binary_compose<AdaptableBinaryFunction,AdaptableUnaryFunction1,AdaptableUnaryFunction2>
binary_function<Arg1, Arg2, Result>
binary_negate<AdaptableBinaryPredicate>
binary_search
binder1st<AdaptableBinaryFunction>
binder2nd<AdaptableBinaryFunction>
bit_vector
bitset<N>
char_producer
char_traits
Character Traits
construct
Container
copy
copy_backward
copy_n
count
count_if
Default Constructible
deque<T, Alloc>
destroy
distance
distance_type
divides<T>
equal
equal_range
equal_to<T>
Equality Comparable
fill
fill_n
find
find_end
find_first_of
find_if
for_each
Forward Container
Forward Iterator
forward_iterator<T, Distance>
forward_iterator_tag
Front Insertion Sequence
front_insert_iterator<FrontInsertionSequence>
Function Objects
generate
generate_n
Generator
get_temporary_buffer
greater<T>
greater_equal<T>
Hash Function
hash<T>
hash_map<Key, Data, HashFcn, EqualKey, Alloc>
hash_multimap<Key, Data, HashFcn, EqualKey, Alloc>
hash_multiset<Key, HashFcn, EqualKey, Alloc>
hash_set<Key, HashFcn, EqualKey, Alloc>
Hashed Associative Container
identity<T>
includes
inner_product
inplace_merge
Input Iterator
input_iterator<T, Distance>
input_iterator_tag
insert_iterator<Container>
iota
is_heap
is_sorted
istream_iterator<T, Distance>
iter_swap
Iterator Tags
iterator_category
iterator_traits<Iterator>
Iterators
less<T>
less_equal<T>
LessThan Comparable
lexicographical_compare
lexicographical_compare_3way
list<T, Alloc>
logical_and<T>
logical_not<T>
logical_or<T>
lower_bound
make_heap
map<Key, Data, Compare, Alloc>
max
max_element
mem_fun1_ref_t<Result, X, Arg>
mem_fun1_t<Result, X, Arg>
mem_fun_ref_t<Result, X>
mem_fun_t<Result, X>
merge
min
min_element
minus<T>
mismatch
modulus<T>
MonoidOperation
multimap<Key, Data, Compare, Alloc>
Multiple Associative Container
Multiple Hashed Associative Container
Multiple Sorted Associative Container
multiplies<T>
multiset<Key, Compare, Alloc>
negate<T>
next_permutation
not_equal_to<T>
nth_element
ostream_iterator<T>
Output Iterator
output_iterator
output_iterator_tag
Pair Associative Container
pair<T1, T2>
partial_sort
partial_sort_copy
partial_sum
partition
plus<T>
pointer_to_binary_function<Arg1, Arg2, Result>
pointer_to_unary_function<Arg, Result>
pop_heap
power
Predicate
prev_permutation
priority_queue<T, Sequence, Compare>
project1st<Arg1, Arg2>
project2nd<Arg1, Arg2>
ptr_fun
push_heap
queue<T, Sequence>
Random Access Container
Random Access Iterator
Random Number Generator
random_access_iterator<T, Distance>
random_access_iterator_tag
random_sample
random_sample_n
random_shuffle
raw_storage_iterator<ForwardIterator, T>
Relational Operators
remove
remove_copy
remove_copy_if
remove_if
replace
replace_copy
replace_copy_if
replace_if
return_temporary_buffer
reverse
reverse_bidirectional_iterator<BidirectionalIterator, T, Reference, Distance>
reverse_copy
reverse_iterator<RandomAccessIterator, T, Reference, Distance>
Reversible Container
rope<T, Alloc>
rotate
rotate_copy
search
search_n
select1st<Pair>
select2nd<Pair>
Sequence
sequence_buffer<Container, buf_sz>
set<Key, Compare, Alloc>
set_difference
set_intersection
set_symmetric_difference
set_union
Simple Associative Container
slist<T, Alloc>
sort
sort_heap
Sorted Associative Container
stable_partition
stable_sort
stack<T, Sequence>
Strict Weak Ordering
subtractive_rng
swap
swap_ranges
temporary_buffer<ForwardIterator, T>
transform
Trivial Iterator
Unary Function
unary_compose<AdaptableUnaryFunction1,AdaptableUnaryFunction2>
unary_function<Arg, Result>
unary_negate<AdaptablePredicate>
uninitialized_copy
uninitialized_copy_n
uninitialized_fill
uninitialized_fill_n
unique
Unique Associative Container
Unique Hashed Associative Container
Unique Sorted Associative Container
unique_copy
upper_bound
value_type
vector<T, Alloc>


The Standard Template Library

 SGI

Index: The Standard Template Library

Associative Container
Back Insertion Sequence
basic_string<charT, traits, Alloc>
bit_vector
bitset<N>
char_producer
Container
deque<T, Alloc>
Forward Container
Front Insertion Sequence
Hash Function
hash<T>
hash_map<Key, Data, HashFcn, EqualKey, Alloc>
hash_multimap<Key, Data, HashFcn, EqualKey, Alloc>
hash_multiset<Key, HashFcn, EqualKey, Alloc>
hash_set<Key, HashFcn, EqualKey, Alloc>
Hashed Associative Container
list<T, Alloc>
map<Key, Data, Compare, Alloc>
multimap<Key, Data, Compare, Alloc>
Multiple Associative Container
Multiple Hashed Associative Container
Multiple Sorted Associative Container
multiset<Key, Compare, Alloc>
Pair Associative Container
priority_queue<T, Sequence, Compare>
queue<T, Sequence>
Random Access Container
Reversible Container
rope<T, Alloc>
Sequence
set<Key, Compare, Alloc>
Simple Associative Container
slist<T, Alloc>
Sorted Associative Container
stack<T, Sequence>
Unique Associative Container
Unique Hashed Associative Container
Unique Sorted Associative Container
vector<T, Alloc>

advance
back_insert_iterator<BackInsertionSequence>
Bidirectional Iterator
bidirectional_iterator<T, Distance>
bidirectional_iterator_tag
distance
distance_type
Forward Iterator
forward_iterator<T, Distance>
forward_iterator_tag
front_insert_iterator<FrontInsertionSequence>
Input Iterator
input_iterator<T, Distance>
input_iterator_tag
insert_iterator<Container>
istream_iterator<T, Distance>
Iterator Tags
iterator_category
iterator_traits<Iterator>
Iterators
ostream_iterator<T>
Output Iterator
output_iterator
output_iterator_tag
Random Access Iterator
random_access_iterator<T, Distance>
random_access_iterator_tag
raw_storage_iterator<ForwardIterator, T>
reverse_bidirectional_iterator<BidirectionalIterator, T, Reference, Distance>
reverse_iterator<RandomAccessIterator, T, Reference, Distance>
sequence_buffer<Container, buf_sz>
Trivial Iterator
value_type

accumulate
adjacent_difference
adjacent_find
advance
binary_search
copy
copy_backward
copy_n
count
count_if
distance
equal
equal_range
fill
fill_n
find
find_end
find_first_of
find_if
for_each
generate
generate_n
includes
inner_product
inplace_merge
iota
is_heap
is_sorted
iter_swap
lexicographical_compare
lexicographical_compare_3way
lower_bound
make_heap
max
max_element
merge
min
min_element
mismatch
next_permutation
nth_element
partial_sort
partial_sort_copy
partial_sum
partition
pop_heap
power
prev_permutation
push_heap
random_sample
random_sample_n
random_shuffle
remove
remove_copy
remove_copy_if
remove_if
replace
replace_copy
replace_copy_if
replace_if
reverse
reverse_copy
rotate
rotate_copy
search
search_n
set_difference
set_intersection
set_symmetric_difference
set_union
sort
sort_heap
stable_partition
stable_sort
swap
swap_ranges
transform
uninitialized_copy
uninitialized_copy_n
uninitialized_fill
uninitialized_fill_n
unique
unique_copy
upper_bound

Adaptable Binary Function
Adaptable Binary Predicate
Adaptable Generator
Adaptable Predicate
Adaptable Unary Function
Binary Function
Binary Predicate
binary_compose<AdaptableBinaryFunction,AdaptableUnaryFunction1,AdaptableUnaryFunction2>
binary_function<Arg1, Arg2, Result>
binary_negate<AdaptableBinaryPredicate>
binder1st<AdaptableBinaryFunction>
binder2nd<AdaptableBinaryFunction>
divides<T>
equal_to<T>
Function Objects
Generator
greater<T>
greater_equal<T>
Hash Function
hash<T>
identity<T>
less<T>
less_equal<T>
logical_and<T>
logical_not<T>
logical_or<T>
mem_fun1_ref_t<Result, X, Arg>
mem_fun1_t<Result, X, Arg>
mem_fun_ref_t<Result, X>
mem_fun_t<Result, X>
minus<T>
modulus<T>
MonoidOperation
multiplies<T>
negate<T>
not_equal_to<T>
plus<T>
pointer_to_binary_function<Arg1, Arg2, Result>
pointer_to_unary_function<Arg, Result>
Predicate
project1st<Arg1, Arg2>
project2nd<Arg1, Arg2>
ptr_fun
Random Number Generator
select1st<Pair>
select2nd<Pair>
Strict Weak Ordering
subtractive_rng
Unary Function
unary_compose<AdaptableUnaryFunction1,AdaptableUnaryFunction2>
unary_function<Arg, Result>
unary_negate<AdaptablePredicate>

Assignable
char_traits
Character Traits
Default Constructible
Equality Comparable
LessThan Comparable
max
min
pair<T1, T2>
Relational Operators

back_insert_iterator<BackInsertionSequence>
binary_compose<AdaptableBinaryFunction,AdaptableUnaryFunction1,AdaptableUnaryFunction2>
binary_negate<AdaptableBinaryPredicate>
binder1st<AdaptableBinaryFunction>
binder2nd<AdaptableBinaryFunction>
front_insert_iterator<FrontInsertionSequence>
insert_iterator<Container>
mem_fun1_ref_t<Result, X, Arg>
mem_fun1_t<Result, X, Arg>
mem_fun_ref_t<Result, X>
mem_fun_t<Result, X>
pointer_to_binary_function<Arg1, Arg2, Result>
pointer_to_unary_function<Arg, Result>
priority_queue<T, Sequence, Compare>
ptr_fun
queue<T, Sequence>
raw_storage_iterator<ForwardIterator, T>
reverse_bidirectional_iterator<BidirectionalIterator, T, Reference, Distance>
reverse_iterator<RandomAccessIterator, T, Reference, Distance>
sequence_buffer<Container, buf_sz>
stack<T, Sequence>
unary_compose<AdaptableUnaryFunction1,AdaptableUnaryFunction2>
unary_negate<AdaptablePredicate>

Allocators
construct
destroy
get_temporary_buffer
raw_storage_iterator<ForwardIterator, T>
return_temporary_buffer
temporary_buffer<ForwardIterator, T>
uninitialized_copy
uninitialized_copy_n
uninitialized_fill
uninitialized_fill_n


The Standard Template Library: Introduction

 SGI

Introduction to the Standard Template Library

The Standard Template Library, or STL, is a C++ library of container classes, algorithms, and iterators; it provides many of the basic algorithms and data structures of computer science. The STL is a generic library, meaning that its components are heavily parameterized: almost every component in the STL is a template. You should make sure that you understand how templates work in C++ before you use the STL.

Containers and algorithms

Like many class libraries, the STL includes container classes: classes whose purpose is to contain other objects. The STL includes the classes vector, list, deque, set, multiset, map, multimap, hash_set, hash_multiset, hash_map, and hash_multimap. Each of these classes is a template, and can be instantiated to contain any type of object. You can, for example, use a vector<int> in much the same way as you would use an ordinary C array, except that vector eliminates the chore of managing dynamic memory allocation by hand.

      vector<int> v(3);            // Declare a vector of 3 elements.
      v[0] = 7;
      v[1] = v[0] + 3;
      v[2] = v[0] + v[1];          // v[0] == 7, v[1] == 10, v[2] == 17

The STL also includes a large collection of algorithms that manipulate the data stored in containers. You can reverse the order of elements in a vector, for example, by using the reverse algorithm.

      reverse(v.begin(), v.end()); // v[0] == 17, v[1] == 10, v[2] == 7

There are two important points to notice about this call to reverse. First, it is a global function, not a member function. Second, it takes two arguments rather than one: it operates on a range of elements, rather than on a container. In this particular case the range happens to be the entire container v.

The reason for both of these facts is the same: reverse, like other STL algorithms, is decoupled from the STL container classes. This means that reverse can be used not only to reverse elements in vectors, but also to reverse elements in lists, and even elements in C arrays. The following program is also valid.

      double A[6] = { 1.2, 1.3, 1.4, 1.5, 1.6, 1.7 };
      reverse(A, A + 6);
      for (int i = 0; i < 6; ++i)
        cout << "A[" << i << "] = " << A[i];

This example uses a range, just like the example of reversing a vector: the first argument to reverse is a pointer to the beginning of the range, and the second argument points one element past the end of the range. This range is denoted [A, A + 6); the asymmetrical notation is a reminder that the two endpoints are different, that the first is the beginning of the range and the second is one past the end of the range.

Iterators

In the example of reversing a C array, the arguments to reverse are clearly of type double*. What are the arguments to reverse if you are reversing a vector, though, or a list? That is, what exactly does reverse declare its arguments to be, and what exactly do v.begin() and v.end() return?

The answer is that the arguments to reverse are iterators, which are a generalization of pointers. Pointers themselves are iterators, which is why it is possible to reverse the elements of a C array. Similarly, vector declares the nested types iterator and const_iterator. In the example above, the type returned by v.begin() and v.end() is vector<int>::iterator. There are also some iterators, such as istream_iterator and ostream_iterator, that aren't associated with containers at all.

Iterators are the mechanism that makes it possible to decouple algorithms from containers: algorithms are templates, and are parameterized by the type of iterator, so they are not restricted to a single type of container. Consider, for example, how to write an algorithm that performs linear search through a range. This is the STL's find algorithm.

      template <class InputIterator, class T>
      InputIterator find(InputIterator first, InputIterator last, const T& value) {
          while (first != last && *first != value) ++first;
          return first;
      }

Find takes three arguments: two iterators that define a range, and a value to search for in that range. It examines each iterator in the range [first, last), proceeding from the beginning to the end, and stops either when it finds an iterator that points to value or when it reaches the end of the range.

First and last are declared to be of type InputIterator, and InputIterator is a template parameter. That is, there isn't actually any type called InputIterator: when you call find, the compiler substitutes the actual type of the arguments for the formal type parameters InputIterator and T. If the first two arguments to find are of type int* and the third is of type int, then it is as if you had called the following function.

      int* find(int* first, int* last, const int& value) {
          while (first != last && *first != value) ++first;
          return first;
      }

Concepts and Modeling

One very important question to ask about any template function, not just about STL algorithms, is what the set of types is that may correctly be substituted for the formal template parameters. Clearly, for example, int* or double* may be substituted for find's formal template parameter InputIterator. Equally clearly, int or double may not: find uses the expression *first, and the dereference operator makes no sense for an object of type int or of type double. The basic answer, then, is that find implicitly defines a set of requirements on types, and that it may be instantiated with any type that satisfies those requirements. Whatever type is substituted for InputIterator must provide certain operations: it must be possible to compare two objects of that type for equality, it must be possible to increment an object of that type, it must be possible to dereference an object of that type to obtain the object that it points to, and so on.

Find isn't the only STL algorithm that has such a set of requirements; the arguments to for_each and count, and other algorithms, must satisfy the same requirements. These requirements are sufficiently important that we give them a name: we call such a set of type requirements a concept, and we call this particular concept Input Iterator. We say that a type conforms to a concept, or that it is a model of a concept, if it satisfies all of those requirements. We say that int* is a model of Input Iterator because int* provides all of the operations that are specified by the Input Iterator requirements.

Concepts are not a part of the C++ language; there is no way to declare a concept in a program, or to declare that a particular type is a model of a concept. Nevertheless, concepts are an extremely important part of the STL. Using concepts makes it possible to write programs that cleanly separate interface from implementation: the author of find only has to consider the interface specified by the concept Input Iterator, rather than the implementation of every possible type that conforms to that concept. Similarly, if you want to use find, you need only to ensure that the arguments you pass to it are models of Input Iterator. This is the reason why find and reverse can be used with lists, vectors, C arrays, and many other types: programming in terms of concepts, rather than in terms of specific types, makes it possible to reuse software components and to combine components together.

Refinement

Input Iterator is, in fact, a rather weak concept: that is, it imposes very few requirements. An Input Iterator must support a subset of pointer arithmetic (it must be possible to increment an Input Iterator using prefix and postfix operator++), but need not support all operations of pointer arithmetic. This is sufficient for find, but some other algorithms require that their arguments satisfy additional requirements. Reverse, for example, must be able to decrement its arguments as well as increment them; it uses the expression --last. In terms of concepts, we say that reverse's arguments must be models of Bidirectional Iterator rather than Input Iterator.

The Bidirectional Iterator concept is very similar to the Input Iterator concept: it simply imposes some additional requirements. The types that are models of Bidirectional Iterator are a subset of the types that are models of Input Iterator: every type that is a model of Bidirectional Iterator is also a model of Input Iterator. Int*, for example, is both a model of Bidirectional Iterator and a model of Input Iterator, but istream_iterator, is only a model of Input Iterator: it does not conform to the more stringent Bidirectional Iterator requirements.

We describe the relationship between Input Iterator and Bidirectional Iterator by saying that Bidirectional Iterator is a refinement of Input Iterator. Refinement of concepts is very much like inheritance of C++ classes; the main reason we use a different word, instead of just calling it "inheritance", is to emphasize that refinement applies to concepts rather than to actual types.

There are actually three more iterator concepts in addition to the two that we have already discussed: the five iterator concepts are Output Iterator, Input Iterator, Forward Iterator, Bidirectional Iterator, and Random Access Iterator; Forward Iterator is a refinement of Input Iterator, Bidirectional Iterator is a refinement of Forward Iterator, and Random Access Iterator is a refinement of Bidirectional Iterator. (Output Iterator is related to the other four concepts, but it is not part of the hierarchy of refinement: it is not a refinement of any of the other iterator concepts, and none of the other iterator concepts are refinements of it.) The Iterator Overview has more information about iterators in general.

Container classes, like iterators, are organized into a hierarchy of concepts. All containers are models of the concept Container; more refined concepts, such as Sequence and Associative Container, describe specific types of containers.

Other parts of the STL

If you understand algorithms, iterators, and containers, then you understand almost everything there is to know about the STL. The STL does, however, include several other types of components.

First, the STL includes several utilities: very basic concepts and functions that are used in many different parts of the library. The concept Assignable, for example, describes types that have assignment operators and copy constructors; almost all STL classes are models of Assignable, and almost all STL algorithms require their arguments to be models of Assignable.

Second, the STL includes some low-level mechanisms for allocating and deallocating memory. Allocators are very specialized, and you can safely ignore them for almost all purposes.

Finally, the STL includes a large collection of function objects, also known as functors. Just as iterators are a generalization of pointers, function objects are a generalization of functions: a function object is anything that you can call using the ordinary function call syntax. There are several different concepts relating to function objects, including Unary Function (a function object that takes a single argument, i.e. one that is called as f(x)) and Binary Function (a function object that takes two arguments, i.e. one that is called as f(x, y)). Function objects are an important part of generic programming because they allow abstraction not only over the types of objects, but also over the operations that are being performed.


Strict Weak Ordering

Category: functors | Component type: concept

Description

A Strict Weak Ordering is a Binary Predicate that compares two objects, returning true if the first precedes the second. This predicate must satisfy the standard mathematical definition of a strict weak ordering. The precise requirements are stated below, but what they roughly mean is that a Strict Weak Ordering has to behave the way that "less than" behaves: if a is less than b then b is not less than a, if a is less than b and b is less than c then a is less than c, and so on.

Refinement of

Binary Predicate

Associated types

First argument type | The type of the Strict Weak Ordering's first argument.
Second argument type | The type of the Strict Weak Ordering's second argument. The first argument type and second argument type must be the same.
Result type | The type returned when the Strict Weak Ordering is called. The result type must be convertible to bool.

Notation

F | A type that is a model of Strict Weak Ordering
X | The type of Strict Weak Ordering's arguments.
f | Object of type F
x, y, z | Object of type X

Definitions

  • Two objects x and y are equivalent if both f(x, y) and f(y, x) are false. Note that an object is always (by the irreflexivity invariant) equivalent to itself.

Valid expressions

None, except for those defined in the Binary Predicate requirements.

Expression semantics

Name | Expression | Precondition | Semantics | Postcondition
Function call | f(x, y) | The ordered pair (x,y) is in the domain of f | Returns true if x precedes y, and false otherwise | The result is either true or false

Complexity guarantees

Invariants

Irreflexivity | f(x, x) must be false.
Antisymmetry | f(x, y) implies !f(y, x)
Transitivity | f(x, y) and f(y, z) imply f(x, z).
Transitivity of equivalence | Equivalence (as defined above) is transitive: if x is equivalent to y and y is equivalent to z, then x is equivalent to z. (This implies that equivalence does in fact satisfy the mathematical definition of an equivalence relation.) [1]

Models

  • less<int>
  • less<double>
  • greater<int>
  • greater<double>

Notes

[1] The first three axioms, irreflexivity, antisymmetry, and transitivity, are the definition of a partial ordering; transitivity of equivalence is required by the definition of a strict weak ordering. A total ordering is one that satisfies an even stronger condition: equivalence must be the same as equality.

See also

LessThan Comparable, less, Binary Predicate, function objects


Strings in SGI STL

This is an attempt to answer some of the questions related to the use of strings with SGI STL.

What's wrong with the string class defined by the draft standard?

There are several problems, but the most serious ones relate to the specification for lifetimes of references to characters in a string. The second committee draft disallows the expression s[1] == s[2] where s is a nonconstant string. This is not simply an oversight; current reference counted implementations may fail for more complicated examples. They may fail even for s[1] == s[2] if the string s is simultaneously examined (merely examined, not necessarily modified) by another thread. It is hard to define precisely what constitutes a correct use of one of the current reference counted implementation.

This problem was partially addressed at the July 1997 meeting of the C++ standardization committee; the solution was to adopt more complicated rules about reference lifetimes. Unfortunately, these new rules still do not address the multi-threading issues.

A related problem was pointed out in the French national body comments on the second committee draft. The following program produces the wrong answer for most reference counted basic_string implementations that we have tested; the problem is that, if two strings share a common representation, they are vulnerable to modification through a pre-existing reference or iterator.

# include <string>
# include <stdio.h>

main() {
   string s("abc");
   string t;
   char & c(s[1]);

   t = s;	// Data typically shared between s and t.
   c = 'z';     // How many strings does this modify?
   if (t[1] == 'z') {
        printf("wrong\n");
   } else {
        printf("right\n");
   }
}

The draft standard (as well as common sense) says that updating a reference to one of s's elements should only modify s, not t as well; the fact that s and t might share a representation is an implementation detail that should have no effect on program behavior. Given the design of basic_string, though, it is very difficult for a reference-counted implementation to satisfy that requirement.

The only known way for a reference-counted implementation to avoid this problem is to mark a string as unsharable whenever there might be an existing reference or iterator to that string. That is, whenever a program obtains a reference or an iterator to a string (e.g. by using operator[] or begin()), that particular string will no longer use reference counting; assignment and copy construction will copy the string's elements instead of just copying a pointer. (We are not aware of any implementation that uses this technique and that also attempts to be thread-safe.)

This is a drastic solution: since almost all ways of referring to characters involve references or iterators, this solution implies, in effect, that the only strings that can be reference-counted are the ones that are never used. In practice, then, a reference counted implementation of basic_string can't achieve the performance gains that one might otherwise expect, since reference counting is forbidden in all but a few special cases.

A different solution is to abandon the goal of reference-counted strings altogether, and to provide a non-reference-counted implementation of basic_string instead. The draft standard permits non-reference-counted implementations, and several vendors already provide them. The performance characteristics of a non-reference-counted basic_string are predicable, and are very similar to those of a vector<char>: copying a string, for example, is always an O(N) operation.

In this implementation, basic_string does not use reference counting.

I have been using a reference counted implementation, and it works fine. Why haven't I seen problems?

The current implementations do work correctly, most of the time: preserving a reference to a character in a string is uncommon. (Although preserving iterators to strings may be more frequent, and exactly the same issues apply to iterators.) Some less contrived sequential programs also fail, though, or else behave differently on different platforms.

Multi-threaded applications that use a reference counted basic_string are likely to fail intermittently, perhaps once every few months; these intermittent failures are difficult to reproduce and debug. But it is likely that a large fraction of multi-threaded clients will fail occasionally, thus making such a library completely inappropriate for multi-threaded use.

So what should I use to represent strings?

There are several possible options, which are appropriate under different circumstances:
Ropes
Use the rope package provided by the SGI STL. This provides all functionality that's likely to be needed. Its interface is similar to the current draft standard, but different enough to allow a correct and thread-safe implementation. It should perform reasonably well for all applications that do not require very frequent small updates to strings. It is the only alternative that scales well to very long strings, i.e. that could easily be used to represent a mail message or a text file as a single string.

The disadvantages are:

  • Single character replacements are slow. Consequently STL algorithms are likely to be slow when updating ropes. (Insertions near the beginning take roughly the same amount of time as single character replacements, and much less time than corresponding insertions for the other string alternatives.)
  • The rope implementation stretches current compiler technology. Portability and compilation time may be an issue in the short term. Pthread performance on non-SGI platforms will be an issue until someone provides machine-specific fast reference counting code. (This is also likely to be an issue for other reference counted implementations.)
C strings
This is likely to be the most efficient way to represent a large collection of very short strings. It is by far the most space efficient alternative for small strings. For short strings, the C library functions in <string.h> provide an efficient set of tools for manipulating such strings. They allow easy communication with the C library. The primary disadvantages are that
  • Operations such as concatenation and substring are much more expensive than for ropes if the strings are long. A C string is not a good representation for a text file in an editor.
  • The user needs to be aware of sharing between string representations. If strings are assigned by copying pointers, an update to one string may affect another.
  • C strings provide no help in storage management. This may be a major issue, although a garbage collector can help alleviate it.
vector<char>
If a string is treated primarily as an array of characters, with frequent in-place updates, it is reasonable to represent it as vector<char> or vector<wchar_t>. The same is true if it will be modified by STL container algorithms. Unlike C strings, vectors handle internal storage management automatically, and operations that modify the length of a string are generally more convenient.

Disadvantages are:

  • Vector assignments are much more expensive than C string pointer assignments; the only way to share string representations is to pass pointers or references to vectors.
  • Most operations on entire strings (e.g. assignment, concatenation) do not scale well to long strings.
  • A number of standard string operations (e.g. concatenation and substring) are not provided with the usual syntax, and must be expressed using generic STL algorithms. This is usually not hard.
  • Conversion to C strings is currently slow, even for short strings. That may change in future implementations.

What about mstring.h, as supplied with SGI's 7.1 compiler?

This package was a minimal adaptation of the freely available Modena strings package. It was intended as a stopgap. We do not intend to develop it further.

It shares some of the reference lifetime problems of other implementations that try to conform to the draft standard. Its exact semantics were never well-defined. Under rare conditions, it will have unexpected semantics for single-threaded applications. It fails on the example given above. We strongly discourage use for multi-threaded applications.


subtractive_rng

Category: functors | Component type: type

Description

Subtractive_rng is a Random Number Generator based on the subtractive method [1]. It is a Unary Function: it takes a single argument N, an unsigned int, and returns an unsigned int that is less than N. Successive calls to the same subtractive_rng object [2] yield a pseudo-random sequence.

Example

int main()
{
  subtractive_rng R;
  for (int i = 0; i < 20; ++i)
    cout << R(5) << ' ';
  cout << endl;
}
// The output is   3 2 3 2 4 3 1 1 2 2 0 3 4 4 4 4 2 1 0 0

Definition

Defined in the standard header functional, and in the nonstandard backward-compatibility header function.h. This function object is an SGI extension; it is not part of the C++ standard.

Template parameters

None.

Model of

Random Number Generator, Adaptable Unary Function

Type requirements

None.

Public base classes

unary_function<unsigned int, unsigned int>

Members

Parameter | Description | Default
argument_type | Adaptable Unary Function | The type of a subtractive_rng's argument: unsigned int.
result_type | Adaptable Unary Function | The type of the result: unsigned int.
subtractive_rng(unsigned int seed) | subtractive_rng | See below.
subtractive_rng() | subtractive_rng | See below.
unsigned int operator()(unsigned int N) | Adaptable Unary Function | Function call. Returns a pseudo-random number in the range [0, N).
void initialize(unsigned int seed) | subtractive_rng | See below.

New members

These members are not defined in the Adaptable Unary Function requirements, but are specific to subtractive_rng.
Member | Description
subtractive_rng(unsigned int seed) | The constructor. Creates a subtractive_rng whose internal state is initialized using seed.
subtractive_rng() | The default constructor. Creates a subtractive_rng initialized using a default value.
void initialize(unsigned int seed) | Re-initializes the internal state of the subtractive_rng, using the value seed.

Notes

[1] See section 3.6 of Knuth for an implementation of the subtractive method in FORTRAN. Section 3.2.2 of Knuth analyzes this class of algorithms. (D. E. Knuth, The Art of Computer Programming. Volume 2: Seminumerical Algorithms, second edition. Addison-Wesley, 1981.)

[2] Note that the sequence produced by a subtractive_rng is completely deterministic, and that the sequences produced by two different subtractive_rng objects are independent of each other. That is: if R1 is a subtractive_rng, then the values returned when R1 is called depend only on R1's seed and on the number of times that R1 has been called. Calls to other subtractive_rng objects are irrelevant. In implementation terms, this is because the class subtractive_rng contains no static members.

See also

Random Number Generator


swap

Category: algorithms | Component type: function

Prototype

template <class Assignable>
void swap(Assignable& a, Assignable& b);

Description

Assigns the contents of a to b and the contents of b to a. This is used as a primitive operation by many other algorithms.

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

  • Assignable is a model of Assignable.

Preconditions

None.

Complexity

Amortized constant time. [1] [2]

Example

int x = 1;
int y = 2;
assert(x == 1 && y == 2);
swap(x, y);
assert(x == 2 && y == 1);

Notes

[1] The time required to swap two objects of type T will obviously depend on the type; "constant time" does not mean that performance will be the same for an 8-bit char as for a 128-bit complex<double>.

[2] This implementation of swap makes one call to a copy constructor and two calls to an assignment operator; roughly, then, it should be expected to take about the same amount of time as three assignments. In many cases, however, it is possible to write a specialized version of swap that is far more efficient. Consider, for example, swapping two vector<double>s each of which has N elements. The unspecialized version requires 3*N assignments of double, but a specialized version requires only nine pointer assignments. This is important because swap is used as a primitive operation in many other STL algorithms, and because containers of containers (list<vector<char> >, for example) are very common. The STL includes specialized versions of swap for all container classes. User-defined types should also provide specialized versions of swap whenever it is possible to write one that is more efficient than the general version.

See also

iter_swap, swap_ranges


swap_ranges

Category: algorithms | Component type: function

Prototype

template <class ForwardIterator1, class ForwardIterator2>
ForwardIterator2 swap_ranges(ForwardIterator1 first1, ForwardIterator1 last1,
                             ForwardIterator2 first2);

Description

Swap_ranges swaps each of the elements in the range [first1, last1) with the corresponding element in the range [first2, first2 + (last1 - first1)). That is, for each integer n such that 0 <= n < (last1 - first1), it swaps *(first1 + n) and *(first2 + n). The return value is first2 + (last1 - first1).

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

ForwardIterator1 and ForwardIterator2 must both be models of Forward Iterator. The value types of ForwardIterator1 and ForwardIterator2 must be convertible to each other.

Preconditions

  • [first1, last1) is a valid range.
  • [first2, first2 + (last1 - first1)) is a valid range.
  • The two ranges [first1, last1) and [first2, first2 + (last1 - first1)) do not overlap.

Complexity

Linear. Exactly last1 - first1 swaps are performed.

Example

vector<int> V1, V2;
V1.push_back(1);
V1.push_back(2);
V2.push_back(3);
V2.push_back(4);

assert(V1[0] == 1 && V1[1] == 2 && V2[0] == 3 && V2[1] == 4);
swap_ranges(V1.begin(), V1.end(), V2.begin());
assert(V1[0] == 3 && V1[1] == 4 && V2[0] == 1 && V2[1] == 2);

Notes

See also

swap, iter_swap.


temporary_buffer<ForwardIterator, T>

Category: allocators | Component type: type

Description

Some algorithms, such as stable_sort and inplace_merge, are adaptive: they attempt to use extra temporary memory to store intermediate results, and their run-time complexity is better if that extra memory is available. These algorithms use temporary_buffer to allocate that extra memory.

temporary_buffer's constructor takes two arguments, first and last, of type ForwardIterator; the constructor allocates a buffer that is large enough to contain N objects of type T, where 0 <= N <= last - first [1], and it fills the buffer with objects of type T. The member functions begin() and end() return iterators that point to the beginning and the end of the buffer.

Note that the elements in the buffer are guaranteed to be initialized; that is, begin() points to an object of type T, not to raw memory. However, the initial values of the buffer's elements are unspecified. You should not rely on them to be initialized to any particular value.

temporary_buffer does not have a copy constructor, or an assignment operator. Those operations would have complicated, and not terribly useful, semantics.

(Earlier versions of the STL used get_temporary_buffer and return_temporary_buffer instead of temporary_buffer. temporary_buffer is more convenient, because it does not require using uninitialized_copy, and in some cases it is also more efficient. Additionally, it is much easier to write exception-safe code with temporary_buffer than with get_temporary_buffer and return_temporary_buffer.)

Example

int main()
{
  vector<int> V(50);
  iota(V.begin(), V.end(), 1);

  temporary_buffer<vector<int>::iterator, int> buf(V.begin(), V.end());
  copy(V.rbegin(), V.rbegin() + buf.size(), buf.begin());
  copy(buf.begin(), buf.end(), ostream_iterator<int>(cout, "\n"));
}

Definition

Defined in the standard header memory, and in the nonstandard backward-compatibility header algo.h. This class is an SGI extension; it is not part of the C++ standard.

Template parameters

Parameter | Description | Default
ForwardIterator | The type of the iterators passed as arguments to temporary_buffer's constructor. |
T | The type of object stored in the temporary buffer. | iterator_traits<ForwardIterator>::value_type [2]

Model of

None. temporary_buffer is vaguely similar to a Container, but it does not provide the entire Container interface. In particular, it is not a model of DefaultConstructible or Assignable.

Type requirements

  • ForwardIterator is a model of Forward Iterator
  • ForwardIterator is mutable.
  • T has a constructor that can take a single argument of ForwardIterator's value type.

Public base classes

None.

Members

Member | Description
temporary_buffer(ForwardIterator first,
                 ForwardIterator last)
Allocates a temporary buffer that holds at most last - first elements of type T, and constructs those elements. The initial values of the elements are unspecified. Precondition: [first, last) is a valid range.
~temporary_buffer() | Destroys the elements in the temporary buffer, and deallocates the buffer itself.
T* begin() | Returns a pointer to the first element in the buffer.
T* end() | Returns a pointer that points one past the last element in the buffer.
ptrdiff_t requested_size() const | Returns the value last - first, where first and last are the arguments that were passed to the constructor.
ptrdiff_t size() const | Returns the number of elements in the temporary buffer, end() - begin(). The return value satisfies the constraint 0 <= size() <= requested_size().

New members

Notes

[1] The requested size is last - first. The size of the temporary buffer is never larger than the requested size, but it might well be smaller; the size might even be zero. The intention is that temporary_buffer will allocate as large a buffer as is possible without hurting performance. Note that determining this maximum size is quite difficult: it depends on cache size, physical versus virtual memory, heap fragmentation, and so on. A good implementation of temporary_buffer must be nonportable.

[2] The iterator_traits mechanism relies on partial specialization of templates. If your compiler does not yet implement this features, then you will not be able to use this default parameter; you will have to provide both template arguments.

See also

[Silicon Surf] [STL Home]
Copyright © 1999 Silicon Graphics, Inc. All Rights Reserved. TrademarkInformation


SGI STL Thread-Safety

 SGI

Thread-safety for SGI STL

SGI STL provides what we believe to be the most useful form of thread-safety. This explains some of the design decisions made in the SGI STL implementation.

Client must lock shared mutable containers

The SGI implementation of STL is thread-safe only in the sense that simultaneous accesses to distinct containers are safe, and simultaneous read accesses to to shared containers are safe. If multiple threads access a single container, and at least one thread may potentially write, then the user is responsible for ensuring mutual exclusion between the threads during the container accesses.

This is the only way to ensure full performance for containers that do not need concurrent access. Locking or other forms of synchronization are typically expensive and should be avoided when not necessary.

It is easy for the client or another library to provide the necessary locking by wrapping the underlying container operations with a lock acquisition and release. For example, it would be possible to provide a locked_queue container adapter that provided a container with atomic queue operations.

For most clients, it would be insufficient to simply make container operations atomic; larger grain atomic actions are needed. If a user's code needs to increment the third element in a vector of counters, it would be insuffcient to guarantee that fetching the third element and storing the third element is atomic; it is also necessary to guarantee that no other updates occur in the middle. Thus it would be useless for vector operations to acquire the lock; the user code must provide for locking in any case.

This decision is different from that made by the Java designers. There are two reasons for that. First, for security reasons Java must guarantee that even in the presence of unprotected concurrent accesses to a container, the integrity of the virtual machine cannot be violated. Such safety constraints were clearly not a driving force behind either C++ or STL. Secondly, performance was a more important design goal for STL then it was for the Java standard library.

On the other hand, this notion of thread-safety is stronger than that provided by reference-counted string implementations that try to follow the CD2 version of the draft standard. Such implementations require locking between multiple readers of a shared string.

Lock implementation

The SGI STL implementation removes all nonconstant static data from container implementations. The only potentially shared static data resides in the allocator implementations. To this end, the code to implement per-class node allocation in HP STL was transformed into inlined code for per-size node allocation in the SGI STL allocators. Currently the only explicit locking is performed inside allocators.

Many other container implementations should also benefit from this design. It will usually be possible to implement thread-safe containers in portable code that does not depend on any particular thread package or locking primitives.

Alloc.h uses three different locking primitives depending on the environment. In addition, it can be forced to perform no locking by defining _NOTHREADS. The three styles of locking are:

  • Pthread mutexes. These are used if _PTHREADS is defined by the user. This may be done on SGI machines, but is not recommended in performance critical code with the currently (March 1997) released versions of the SGI Pthreads libraries.
  • Win32 critical sections. These are used by default for win32 compilations with compiler options that request multi-threaded code.
  • An SGI specific spin-lock implementation that is usable with both pthread and sproc threads. This could serve as a prototype implementation for other platforms. This is the default on SGI/MIPS platforms.

It would be preferable if we could always use the OS-supplied locking primitives. Unfortunately, these often do not perform well, for very short critical sections such as those used by the allocator.

Allocation intensive applications using Pthreads to obtain concurrency on multiprocessors should consider using pthread_alloc from pthread_alloc.h. It imposes the restriction that memory deallocated by a thread can only be reallocated by that thread. However, it often obtains significant performance advantages as a result.


multiplies<T>

Category: functors | Component type: type

Description

Multiplies<T> [1] is a function object. Specifically, it is an Adaptable Binary Function. If f is an object of class multiplies<T> and x and y are objects of class T, then f(x,y) returns x*y.

Example

Each element in V3 will be the product of the corresponding elements in V1 and V2
const int N = 1000;
vector<double> V1(N);
vector<double> V2(N);
vector<double> V3(N);

iota(V1.begin(), V1.end(), 1);
fill(V2.begin(), V2.end(), 75);

assert(V2.size() >= V1.size() && V3.size() >= V1.size());
transform(V1.begin(), V1.end(), V2.begin(), V3.begin(),
          multiplies<double>());

Definition

Defined in the standard header functional, and in the nonstandard backward-compatibility header function.h.

Template parameters

Parameter | Description | Default
T | The function object's argument type and result type. |

Model of

Adaptable Binary Function, Default Constructible

Type requirements

T must be a numeric type; if x and y are objects of type T, then x*y must be defined and must have a return type that is convertible to T. T must be Assignable.

Public base classes

binary_function<T, T, T>

Members

Member | Where defined | Description
first_argument_type | Adaptable Binary Function | The type of the first argument: T
second_argument_type | Adaptable Binary Function | The type of the second argument: T
result_type | Adaptable Binary Function | The type of the result: T
T operator()(const T& x, const T& y) | Adaptable Binary Function | Function call operator. The return value is x * y.
multiplies() [1] | Default Constructible | The default constructor.

New members

All of multiplies's members are defined in the Adaptable Binary Function and Default Constructible requirements. Multiplies does not introduce any new members.

Notes

[1] Warning: the name of this function object has been changed from times to multiplies. The name was changed for two reasons. First, it is called multiplies in the C++ standard. Second, the name times conflicts with a function in the Unix header <sys/times.h>.

See also

The Function Object overview, Adaptable Binary Function, binary_function, plus, minus, divides, modulus, negate


transform

Category: algorithms | Component type: function

Prototype

Transform is an overloaded name; there are actually two transform functions.
template <class InputIterator, class OutputIterator, class UnaryFunction>
OutputIterator transform(InputIterator first, InputIterator last,
                         OutputIterator result, UnaryFunction op);

template <class InputIterator1, class InputIterator2, class OutputIterator,
          class BinaryFunction>
OutputIterator transform(InputIterator1 first1, InputIterator1 last1,
                         InputIterator2 first2, OutputIterator result,
                         BinaryFunction binary_op);

Description

Transform performs an operation on objects; there are two versions of transform, one of which uses a single range of Input Iterators and one of which uses two ranges of Input Iterators.

The first version of transform performs the operation op(*i) for each iterator i in the range [first, last), and assigns the result of that operation to *o, where o is the corresponding output iterator. That is, for each n such that 0 <= n < last - first, it performs the assignment *(result + n) = op(*(first + n)). The return value is result + (last - first).

The second version of transform is very similar, except that it uses a Binary Function instead of a Unary Function: it performs the operation op(*i1, *i2) for each iterator i1 in the range [first1, last1) and assigns the result to *o, where i2 is the corresponding iterator in the second input range and where o is the corresponding output iterator. That is, for each n such that 0 <= n < last1 - first1, it performs the assignment *(result + n) = op(*(first1 + n), *(first2 + n). The return value is result + (last1 - first1).

Note that transform may be used to modify a sequence "in place": it is permissible for the iterators first and result to be the same. [1]

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

For the first (unary) version:
  • InputIterator must be a model of Input Iterator.
  • OutputIterator must be a model of Output Iterator.
  • UnaryFunction must be a model of Unary Function.
  • InputIterator's value type must be convertible to UnaryFunction's argument type.
  • UnaryFunction's result type must be convertible to a type in OutputIterator's set of value types.
For the second (binary) version:
  • InputIterator1 and InputIterator2 must be models of Input Iterator.
  • OutputIterator must be a model of Output Iterator.
  • BinaryFunction must be a model of Binary Function.
  • InputIterator1's and InputIterator2's value types must be convertible, respectively, to BinaryFunction's first and second argument types.
  • UnaryFunction's result type must be convertible to a type in OutputIterator's set of value types.

Preconditions

For the first (unary) version:
  • [first, last) is a valid range.
  • result is not an iterator within the range [first+1, last). [1]
  • There is enough space to hold all of the elements being copied. More formally, the requirement is that [result, result + (last - first)) is a valid range.
For the second (binary) version:
  • [first1, last1) is a valid range.
  • [first2, first2 + (last1 - first1)) is a valid range.
  • result is not an iterator within the range [first1+1, last1) or [first2 + 1, first2 + (last1 - first1)).
  • There is enough space to hold all of the elements being copied. More formally, the requirement is that [result, result + (last1 - first1)) is a valid range.

Complexity

Linear. The operation is applied exactly last - first times in the case of the unary version, or last1 - first1 in the case of the binary version.

Example

Replace every number in an array with its negative.
const int N = 1000;
double A[N];
iota(A, A+N, 1);

transform(A, A+N, A, negate<double>());

Calculate the sum of two vectors, storing the result in a third vector.

const int N = 1000;
vector<int> V1(N);
vector<int> V2(N);
vector<int> V3(N);

iota(V1.begin(), V1.end(), 1);
fill(V2.begin(), V2.end(), 75);

assert(V2.size() >= V1.size() && V3.size() >= V1.size());
transform(V1.begin(), V1.end(), V2.begin(), V3.begin(),
          plus<int>());

Notes

[1] The Output Iterator result is not permitted to be the same as any of the Input Iterators in the range [first, last), with the exception of first itself. That is: transform(V.begin(), V.end(), V.begin(), fabs) is valid, but transform(V.begin(), V.end(), V.begin() + 1, fabs) is not.

See also

The function object overview, copy, generate, fill


Trivial Iterator

Category: iterators | Component type: concept

Description

A Trivial Iterator is an object that may be dereferenced to refer to some other object. Arithmetic operations (such as increment and comparison) are not guaranteed to be supported.

Refinement of

Assignable, Equality Comparable, Default Constructible

Associated types

Value type The type of the value obtained by dereferencing a Trivial Iterator

Notation

X | A type that is a model of Trivial Iterator
T | The value type of X
x, y | Object of type X
t | Object of type T

Definitions

A type that is a model of Trivial Iterator may be mutable, meaning that the values referred to by objects of that type may be modified, or constant, meaning that they may not. For example, int* is a mutable iterator type and const int* is a constant iterator type. If an iterator type is mutable, this implies that its value type is a model of Assignable; the converse, though, is not necessarily true.

A Trivial Iterator may have a singular value, meaning that the results of most operations, including comparison for equality, are undefined. The only operation that a is guaranteed to be supported is assigning a nonsingular iterator to a singular iterator.

A Trivial Iterator may have a dereferenceable value, meaning that dereferencing it yields a well-defined value. Dereferenceable iterators are always nonsingular, but the converse is not true. For example, a null pointer is nonsingular (there are well defined operations involving null pointers) even thought it is not dereferenceable.

Invalidating a dereferenceable iterator means performing an operation after which the iterator might be nondereferenceable or singular. For example, if p is a pointer, then delete p invalidates p.

Valid expressions

In addition to the expressions defined in Assignable, Equality Comparable, and Default Constructible, the following expressions must be valid.
Name | Expression | Type requirements | Return type
Default constructor | X x |  |
Dereference | *x |  | Convertible to T [1]
Dereference assignment | *x = t | X is mutable |
Member access | x->m [2] | T is a type for which x.m is defined |

Expression semantics

Name | Expression | Precondition | Semantics | Postcondition
Default constructor | X x |  |  | x is singular
Dereference | *x | x is dereferenceable |  |
Dereference assignment | *x = t | x is dereferenceable |  | *x is a copy of t
Member access | x->m | x is dereferenceable | Equivalent to (*x).m |

Complexity guarantees

The complexity of operations on trivial iterators is guaranteed to be amortized constant time.

Invariants

Identity x == y if and only if &*x == &*y

Models

  • A pointer to an object that is not part of an array.

Notes

[1] The requirement for the return type of *x is specified as "convertible to T", rather than simply T, because it sometimes makes sense for an iterator to return some sort of proxy object instead of the object that the iterator conceptually points to. Proxy objects are implementation details rather than part of an interface (one use of them, for example, is to allow an iterator to behave differently depending on whether its value is being read or written), so the value type of an iterator that returns a proxy is still T.

[2] Defining operator-> for iterators depends on a feature that is part of the C++ language but that is not yet implemented by all C++ compilers. If your compiler does not yet support this feature, the workaround is to use (*it).m instead of it->m.

See also

Input Iterator, Output Iterator, Forward Iterator, Bidirectional Iterator, Random Access Iterator, Iterator Overview


Unary Function

Category: functors | Component type: concept

Description

A Unary Function is a kind of function object: an object that is called as if it were an ordinary C++ function. A Unary Function is called with a single argument.

Refinement of

Assignable

Associated types

Argument type | The type of the Unary Function's argument.
Result type | The type returned when the Unary Function is called

Notation

F | A type that is a model of Unary Function
X | The argument type of F
Result | The result type of F
f | Object of type F
x | Object of type X

Definitions

The domain of a Unary Function is the set of all permissible values for its argument.

The range of a Unary Function is the set of all possible values that it may return.

Valid expressions

Name | Expression | Type requirements | Return type
Function call | f(x) |  | Result

Expression semantics

Name | Expression | Precondition | Semantics | Postcondition
Function call | f(x) | x is in f's domain | Calls f with x as an argument, and returns a value of type Result [1] | The return value is in f's range

Complexity guarantees

Invariants

Models

  • Result (*)(X)

Notes

[1] Two different invocations of f may return different results, even if f is called with the same arguments both times. A Unary Function may refer to local state, perform I/O, and so on. The expression f(x) is permitted to change f's state.

See also

Function Object overview, Generator, Binary Function Adaptable Unary Function


unary_compose<AdaptableUnaryFunction1,AdaptableUnaryFunction2>

Categories: functors, adaptors | Component type: type

Description

Unary_compose is a function object adaptor. If f and g are both Adaptable Unary Functions, and if g's return type is convertible to f's argument type, then unary_compose can be used to create a function object h such that h(x) is the same as f(g(x)). [1] As with other function object adaptors, the easiest way to create a unary_compose is to use the helper function compose1. It is possible to call unary_compose's constructor directly, but there is usually no reason to do so.

Example

Calculates the negative of the sines of the elements in a vector, where the elements are angles measured in degrees. Since the C library function sin takes its arguments in radians, this operation is the composition of three operations: negation, sin, and the conversion of degrees to radians.
vector<double> angles;
vector<double> sines;
const double pi = 3.14159265358979323846;
...
assert(sines.size() >= angles.size());
transform(angles.begin(), angles.end(), sines.begin(),
          compose1(negate<double>(),
                   compose1(ptr_fun(sin),
                            bind2nd(multiplies<double>(), pi / 180.))));

Definition

Defined in the standard header functional, and in the nonstandard backward-compatibility header function.h. The unary_compose class is an SGI extension; it is not part of the C++ standard.

Template parameters

Parameter | Description | Default
AdaptableUnaryFunction1 | The type of the first operand in the function composition operation. That is, if the composition is written f o g [1], then AdaptableUnaryFunction1 is the type of the function object f. |
AdaptableUnaryFunction2 | The type of the second operand in the function composition operation. That is, if the composition is written f o g [1], then AdaptableUnaryFunction1 is the type of the function object g. |

Model of

Adaptable Unary Function

Type requirements

AdaptableUnaryFunction1 and AdaptableUnaryFunction2 must both be models of Adaptable Unary Function. AdaptableUnaryFunction2::result_type must be convertible to AdaptableUnaryFunction1::argument_type.

Public base classes

unary_function<AdaptableUnaryFunction2::argument_type,
               AdaptableUnaryFunction1::result_type>

Members

Member | Where defined | Description
argument_type | Adaptable Unary Function | The type of the function object's argument: AdaptableUnaryFunction2::argument_type.
result_type | Adaptable Unary Function | The type of the result: AdaptableUnaryFunction1::result_type
unary_compose(const AdaptableUnaryFunction1& f,
              const AdaptableUnaryFunction2& g);
unary_compose See below.
template <class AdaptableUnaryFunction1, class AdaptableUnaryFunction2>
unary_compose<AdaptableUnaryFunction1, AdaptableUnaryFunction2>
compose1(const AdaptableUnaryFunction1& op1,
         const AdaptableUnaryFunction2& op2);
unary_compose See below.

New members

These members are not defined in the Adaptable Unary Function requirements, but are specific to unary_compose.
Member Description
unary_compose(const AdaptableUnaryFunction1& f,
              const AdaptableUnaryFunction2& g);
The constructor. Constructs a unary_compose object that represents the function object f o g. [1]
template <class AdaptableUnaryFunction1, class AdaptableUnaryFunction2>
unary_compose<AdaptableUnaryFunction1, AdaptableUnaryFunction2>
compose1(const AdaptableUnaryFunction1& op1,
         const AdaptableUnaryFunction2& op2);
Creates a unary_compose object. If f and g are, respectively, of classes AdaptableUnaryFunction1 and AdaptableUnaryFunction2, then compose1(f, g) is equivalent to unary_compose<AdaptableUnaryFunction1, AdaptableUnaryFunction2>(f, g), but is more convenient. This is a global function, not a member function.

Notes

[1] This operation is called function composition, hence the name unary_compose. It is often represented in mathematics as the operation f o g, where f o g is a function such that (f o g)(x) == f(g(x)). Function composition is a very important concept in algebra. It is also extremely important as a method of building software components out of other components, because it makes it possible to construct arbitrarily complicated function objects out of simple ones.

See also

The function object overview, binary_compose, binder1st, binder2nd.


unary_function<Arg, Result>

Category: functors | Component type: type

Description

Unary_function is an empty base class: it contains no member functions or member variables, but only type information. The only reason it exists is to make it more convenient to define types that are models of the concept Adaptable Unary Function. Specifically, any model of Adaptable Unary Function must define nested typedefs. Those typedefs are provided by the base class unary_function.

Example

struct sine : public unary_function<double, double> {
    double operator()(double x) { return sin(x); }
};

Definition

Defined in the standard header functional, and in the nonstandard backward-compatibility header function.h.

Template parameters

Parameter | Description | Default
Arg | The function object's argument type |
Result | The function object's result type |

Model of

Assignable, Default Constructible

Type requirements

Public base classes

None.

Members

Member | Where defined | Description
argument_type | unary_function | See below.
result_type | unary_function | See below.

New members

These members are not defined in the Assignable and Default Constructible requirements, but are specific to unary_function.
Member | Description
argument_type | The function object's argument type. This is a typedef for the template parameter Arg.
result_type | The function object's result type. This is a typedef for the template parameter Result.

Notes

See also

The Function Object overview, Adaptable Unary Function, binary_function


unary_negate<AdaptablePredicate>

Categories: functors, adaptors | Component type: type

Description

Unary_negate is a function object adaptor: it is an Adaptable Predicate that represents the logical negation of some other Adaptable Predicate. That is: if f is an object of class unary_negate<AdaptablePredicate>, then there exists an object pred of class AdaptablePredicate such that f(x) always returns the same value as !pred(x). [1] There is rarely any reason to construct a unary_negate directly; it is almost always easier to use the helper function not1.

Example

Finds the first element in a list that does not lie in the range from 1 to 10.
list<int> L;
...
list<int>::iterator in_range =
     find_if(L.begin(), L.end(),
             not1(compose2(logical_and<bool>(),
                           bind2nd(greater_equal<int>(), 1),
                           bind2nd(less_equal<int>(), 10))));
assert(in_range == L.end() || !(*in_range >= 1 && *in_range <= 10));

Definition

Defined in the standard header functional, and in the nonstandard backward-compatibility header function.h.

Template parameters

Parameter | Description | Default
AdaptablePredicate | The type of the function object that this unary_negate is the logical negation of. |

Model of

Adaptable Predicate

Type requirements

AdaptablePredicate must be a model of Adaptable Predicate.

Public base classes

unary_function<AdaptablePredicate::argument_type, bool>

Members

Member | Where defined | Description
argument_type | Adaptable Unary Function | The type of the argument: AdaptablePredicate::argument_type
result_type | Adaptable Unary Function | The type of the result: bool
bool operator()(argument_type) | Unary Function | Function call operator.
unary_negate(const AdaptablePredicate& pred)
unary_negate See below.
template <class AdaptablePredicate>
unary_negate<AdaptablePredicate>
not1(const AdaptablePredicate& pred);
unary_negate See below.

New members

These members are not defined in the Adaptable Predicate requirements, but are specific to unary_negate.
Member Description
unary_negate(const AdaptablePredicate& pred)
The constructor. Creates a unary_negate<AdaptablePredicate> whose underlying predicate is pred.
template <class AdaptablePredicate>
unary_negate<AdaptablePredicate>
not1(const AdaptablePredicate& pred);
If p is of type AdaptablePredicate then not1(p) is equivalent to unary_negate<AdaptablePredicate>(p), but more convenient. This is a global function, not a member function.

Notes

[1] Strictly speaking, unary_negate is redundant. It can be constructed using the function object logical_not and the adaptor unary_compose.

See also

The function object overview, Adaptable Predicate, Predicate, binary_negate, unary_compose, binary_compose


uninitialized_copy

Categories: allocators, algorithms | Component type: function

Prototype

template <class InputIterator, class ForwardIterator>
ForwardIterator uninitialized_copy(InputIterator first, InputIterator last,
                                   ForwardIterator result);

Description

In C++, the operator new allocates memory for an object and then creates an object at that location by calling a constructor. Occasionally, however, it is useful to separate those two operations. [1] If each iterator in the range [result, result + (last - first)) points to uninitialized memory, then uninitialized_copy creates a copy of [first, last) in that range. That is, for each iterator i in the input range, uninitialized_copy creates a copy of *i in the location pointed to by the corresponding iterator in the output range by calling construct(&*(result + (i - first)), *i).

Definition

Defined in the standard header memory, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

  • InputIterator is a model of Input Iterator.
  • ForwardIterator is a model of Forward Iterator.
  • ForwardIterator is mutable.
  • ForwardIterator's value type has a constructor that takes a single argument whose type is InputIterator's value type.

Preconditions

  • [first, last) is a valid range.
  • [result, result + (last - first)) is a valid range.
  • Each iterator in [result, result + (last - first)) points to a region of uninitialized memory that is large enough to store a value of ForwardIterator's value type.

Complexity

Linear. Exactly last - first constructor calls.

Example

class Int {
public:
  Int(int x) : val(x) {}
  int get() { return val; }
private:
  int val;
};

int main()
{
  int A1[] = {1, 2, 3, 4, 5, 6, 7};
  const int N = sizeof(A1) / sizeof(int);

  Int* A2 = (Int*) malloc(N * sizeof(Int));
  uninitialized_copy(A1, A1 + N, A2);
}

Notes

[1] In particular, this sort of low-level memory management is used in the implementation of some container classes.

See also

Allocators, construct, destroy, uninitialized_fill, uninitialized_fill_n, raw_storage_iterator


uninitialized_copy_n

Categories: allocators, algorithms | Component type: function

Prototype

template <class InputIterator, class Size, class ForwardIterator>
ForwardIterator uninitialized_copy_n(InputIterator first, Size count,
                                     ForwardIterator result);

Description

In C++, the operator new allocates memory for an object and then creates an object at that location by calling a constructor. Occasionally, however, it is useful to separate those two operations. [1] If each iterator in the range [result, result + n) points to uninitialized memory, then uninitialized_copy_n creates a copy of [first, first + n) in that range. That is, for each iterator i in the input range, uninitialized_copy_n creates a copy of *i in the location pointed to by the corresponding iterator in the output range by calling construct(&*(result + (i - first)), *i).

Definition

Defined in the standard header memory, and in the nonstandard backward-compatibility header algo.h. This function is an SGI extension; it is not part of the C++ standard.

Requirements on types

  • InputIterator is a model of Input Iterator.
  • Size is an integral type.
  • ForwardIterator is a model of Forward Iterator.
  • ForwardIterator is mutable.
  • ForwardIterator's value type has a constructor that takes a single argument whose type is InputIterator's value type.

Preconditions

  • n >= 0
  • [first, first + n) is a valid range.
  • [result, result + n) is a valid range.
  • Each iterator in [result, result + n) points to a region of uninitialized memory that is large enough to store a value of ForwardIterator's value type.

Complexity

Linear. Exactly n constructor calls.

Example

class Int {
public:
  Int(int x) : val(x) {}
  int get() { return val; }
private:
  int val;
};

int main()
{
  int A1[] = {1, 2, 3, 4, 5, 6, 7};
  const int N = sizeof(A1) / sizeof(int);

  Int* A2 = (Int*) malloc(N * sizeof(Int));
  uninitialized_copy_n(A1, N, A2);
}

Notes

[1] In particular, this sort of low-level memory management is used in the implementation of some container classes.

[2] Uninitialized_copy_n is almost, but not quite, redundant. If first is an input iterator, as opposed to a forward iterator, then the uninitialized_copy_n operation can't be expressed in terms of uninitialized_copy.

See also

Allocators, construct, destroy, uninitialized_copy, uninitialized_fill, uninitialized_fill_n, raw_storage_iterator


uninitialized_fill

Categories: allocators, algorithms | Component type: function

Prototype

template <class ForwardIterator, class T>
void uninitialized_fill(ForwardIterator first, ForwardIterator last,
                        const T& x);

Description

In C++, the operator new allocates memory for an object and then creates an object at that location by calling a constructor. Occasionally, however, it is useful to separate those two operations. [1] If each iterator in the range [first, last) points to uninitialized memory, then uninitialized_fill creates copies of x in that range. That is, for each iterator i in the range [first, last), uninitialized_copy creates a copy of x in the location pointed to i by calling construct(&*i, x).

Definition

Defined in the standard header memory, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

  • ForwardIterator is a model of Forward Iterator.
  • ForwardIterator is mutable.
  • ForwardIterator's value type has a constructor that takes a single argument of type T.

Preconditions

  • [first, last) is a valid range.
  • Each iterator in [first, last) points to a region of uninitialized memory that is large enough to store a value of ForwardIterator's value type.

Complexity

Linear. Exactly last - first constructor calls.

Example

class Int {
public:
  Int(int x) : val(x) {}
  int get() { return val; }
private:
  int val;
};

int main()
{
  const int N = 137;

  Int val(46);
  Int* A = (Int*) malloc(N * sizeof(Int));
  uninitialized_fill(A, A + N, val);
}

Notes

[1] In particular, this sort of low-level memory management is used in the implementation of some container classes.

See also

Allocators, construct, destroy, uninitialized_copy, uninitialized_fill_n, raw_storage_iterator


uninitialized_fill_n

Categories: allocators, algorithms | Component type: function

Prototype

template <class ForwardIterator, class Size, class T>
ForwardIterator uninitialized_fill_n(ForwardIterator first, Size n,
                                     const T& x);

Description

In C++, the operator new allocates memory for an object and then creates an object at that location by calling a constructor. Occasionally, however, it is useful to separate those two operations. [1] If each iterator in the range [first, first + n) points to uninitialized memory, then uninitialized_fill_n creates copies of x in that range. That is, for each iterator i in the range [first, first + n), uninitialized_fill_n creates a copy of x in the location pointed to i by calling construct(&*i, x).

Definition

Defined in the standard header memory, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

  • ForwardIterator is a model of Forward Iterator.
  • ForwardIterator is mutable.
  • Size is an integral type that is convertible to ForwardIterator's distance type.
  • ForwardIterator's value type has a constructor that takes a single argument of type T.

Preconditions

  • n is nonnegative.
  • [first, first + n) is a valid range.
  • Each iterator in [first, first + n) points to a region of uninitialized memory that is large enough to store a value of ForwardIterator's value type.

Complexity

Linear. Exactly n constructor calls.

Example

class Int {
public:
  Int(int x) : val(x) {}
  int get() { return val; }
private:
  int val;
};

int main()
{
  const int N = 137;

  Int val(46);
  Int* A = (Int*) malloc(N * sizeof(Int));
  uninitialized_fill_n(A, N, val);
}

Notes

[1] In particular, this sort of low-level memory management is used in the implementation of some container classes.

See also

Allocators, construct, destroy, uninitialized_copy, uninitialized_fill, raw_storage_iterator


unique

Category: algorithms | Component type: function

Prototype

Unique is an overloaded name; there are actually two unique functions.
template <class ForwardIterator>
ForwardIterator unique(ForwardIterator first, ForwardIterator last);

template <class ForwardIterator, class BinaryPredicate>
ForwardIterator unique(ForwardIterator first, ForwardIterator last,
                       BinaryPredicate binary_pred);

Description

Every time a consecutive group of duplicate elements appears in the range [first, last), the algorithm unique removes all but the first element. That is, unique returns an iterator new_last such that the range [first, new_last) contains no two consecutive elements that are duplicates. [1] The iterators in the range [new_last, last) are all still dereferenceable, but the elements that they point to are unspecified. Unique is stable, meaning that the relative order of elements that are not removed is unchanged.

The reason there are two different versions of unique is that there are two different definitions of what it means for a consecutive group of elements to be duplicates. In the first version, the test is simple equality: the elements in a range [f, l) are duplicates if, for every iterator i in the range, either i == f or else *i == *(i-1). In the second, the test is an arbitrary Binary Predicate binary_pred: the elements in [f, l) are duplicates if, for every iterator i in the range, either i == f or else binary_pred(*i, *(i-1)) is true. [2]

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

For the first version:
  • ForwardIterator is a model of Forward Iterator.
  • ForwardIterator is mutable.
  • ForwardIterator's value type is Equality Comparable.
For the second version:
  • ForwardIterator is a model of Forward Iterator.
  • ForwardIterator is mutable.
  • BinaryPredicate is a model of Binary Predicate. [3]
  • ForwardIterator's value type is convertible to BinaryPredicate's first argument type and to BinaryPredicate's second argument type.

Preconditions

  • [first, last) is a valid range.

Complexity

Linear. Exactly (last - first) - 1 applications of operator== (in the case of the first version of unique) or of binary_pred (in the case of the second version).

Example

Remove duplicates from consecutive groups of equal ints.
vector<int> V;
V.push_back(1);
V.push_back(3);
V.push_back(3);
V.push_back(3);
V.push_back(2);
V.push_back(2);
V.push_back(1);

vector<int>::iterator new_end = unique(V.begin(), V.end());
copy(V.begin(), new_end, ostream_iterator<int>(cout, " "));
    // The output it "1 3 2 1".

Remove all duplicates from a vector of chars, ignoring case. First sort the vector, then remove duplicates from consecutive groups.

inline bool eq_nocase(char c1, char c2) { return tolower(c1) == tolower(c2); }
inline bool lt_nocase(char c1, char c2) { return tolower(c1) < tolower(c2); }

int main()
{
  const char init[] = "The Standard Template Library";
  vector<char> V(init, init + sizeof(init));
  sort(V.begin(), V.end(), lt_nocase);
  copy(V.begin(), V.end(), ostream_iterator<char>(cout));
  cout << endl;
  vector<char>::iterator new_end = unique(V.begin(), V.end(), eq_nocase);
  copy(V.begin(), new_end, ostream_iterator<char>(cout));
  cout << endl;
}
// The output is:
//    aaaabddeeehiLlmnprrrStTtTy
//  abdehiLmnprSty

Notes

[1] Note that the meaning of "removal" is somewhat subtle. Unique, like remove, does not destroy any iterators and does not change the distance between first and last. (There's no way that it could do anything of the sort.) So, for example, if V is a vector, remove(V.begin(), V.end(), 0) does not change V.size(): V will contain just as many elements as it did before. Unique returns an iterator that points to the end of the resulting range after elements have been removed from it; it follows that the elements after that iterator are of no interest. If you are operating on a Sequence, you may wish to use the Sequence's erase member function to discard those elements entirely.

[2] Strictly speaking, the first version of unique is redundant: you can achieve the same functionality by using an object of class equal_to as the Binary Predicate argument. The first version is provided strictly for the sake of convenience: testing for equality is an important special case.

[3] BinaryPredicate is not required to be an equivalence relation. You should be cautious, though, about using unique with a Binary Predicate that is not an equivalence relation: you could easily get unexpected results.

See also

Binary Predicate, remove, remove_if, unique_copy, adjacent_find,


Unique Associative Container

Category: containers | Component type: concept

Description

A Unique Associative Container is an Associative Container with the property that each key in the container is unique: no two elements in a Unique Associative Container have the same key.

Refinement of

Associative Container

Associated types

None, except for those defined by Associative Container.

Notation

X | A type that is a model of Unique Associative Container
a | Object of type X
t | Object of type X::value_type
k | Object of type X::key_type
p, q | Object of type X::iterator

Definitions

Valid expressions

In addition to the expressions defined in Associative Container, the following expressions must be valid.
Name | Expression | Type requirements | Return type
Range constructor
X(i, j)
X a(i, j);
i and j are Input Iterators whose value type is convertible to T [1]
Insert element | a.insert(t) | pair<X::iterator, bool>
Insert range | a.insert(i, j) | i and j are Input Iterators whose value type is convertible to X::value_type. [1] | void
Count | a.count(k) | size_type

Expression semantics

Name | Expression | Precondition | Semantics | Postcondition
Range constructor
X(i, j)
X a(i, j);
[i,j) is a valid range. Creates an associative container that contains all of the elements in the range [i,j) that have unique keys. size() is less than or equal to the distance from i to j.
Insert element | a.insert(t) | Inserts t into a if and only if a does not already contain an element whose key is the same as the key of t. The return value is a pair P. P.first is an iterator pointing to the element whose key is the same as the key of t. P.second is a bool: it is true if t was actually inserted into a, and false if t was not inserted into a, i.e. if a already contained an element with the same key as t. | P.first is a dereferenceable iterator. *(P.first) has the same key as t. The size of a is incremented by 1 if and only if P.second is true.
Insert range | a.insert(i, j) | [i, j) is a valid range. | Equivalent to a.insert(t) for each object t that is pointed to by an iterator in the range [i, j). Each element is inserted into a if and only if a does not already contain an element with the same key. | The size of a is incremented by at most j - i.
Count | a.count(k) | Returns the number of elements in a whose keys are the same as k. | The return value is either 0 or 1.

Complexity guarantees

Average complexity for insert element is at most logarithmic.

Average complexity for insert range is at most O(N * log(size() + N)), where N is j - i.

Invariants

Uniqueness No two elements have the same key. Equivalently, this means that for every object k of type key_type, a.count(k) returns either 0 or 1.

Models

  • set
  • map
  • hash_set
  • hash_map

Notes

[1] At present (early 1998), not all compilers support "member templates". If your compiler supports member templates then i and j may be of any type that conforms to the Input Iterator requirements. If your compiler does not yet support member templates, however, then i and j must be of type const T* or of type X::const_iterator.

See also

Associative Container, Multiple Associative Container, Unique Sorted Associative Container, Multiple Sorted Associative Container


Unique Hashed Associative Container

Category: containers | Component type: concept

Description

A Unique Hashed Associative Container is a Hashed Associative Container that is also a Unique Associative Container. That is, it is a Hashed Associative Container with the property that no two elements in the container have the same key.

Refinement of

Hashed Associative Container, Unique Associative Container

Associated types

None, except for those described in the Hashed Associative Container and Unique Associative Container requirements.

Notation

X | A type that is a model of Hashed Associative Container
a | Object of type X
t | Object of type X::value_type
k | Object of type X::key_type
p, q | Object of type X::iterator
n | Object of type X::size_type
h | Object of type X::hasher
c | Object of type X::key_equal

Definitions

Valid expressions

In addition to the expressions defined in Hashed Associative Container and Unique Associative Container, the following expressions must be valid.
Name Expression Type requirements Return type
Range constructor
X(i, j)
X a(i, j);
i and j are Input Iterators whose value type is convertible to T [1]. X
Range constructor with bucket count
X(i, j, n)
X a(i, j, n);
i and j are Input Iterators whose value type is convertible to T [1]. X
Range constructor with hash function
X(i, j, n, h)
X a(i, j, n, h);
i and j are Input Iterators whose value type is convertible to T [1]. X
Range constructor with key equal
X(i, j, n, h, k)
X a(i, j, n, h, k);
i and j are Input Iterators whose value type is convertible to T [1]. X

Expression semantics

Name Expression Precondition Semantics Postcondition
Range constructor
X(i, j)
X a(i, j);
[i,j) is a valid range. Creates an associative container that contains all of the elements in the range [i,j) that have unique keys, using hasher() as the hash function and key_equal() as the key equality function. size() is less than or equal to the distance from i to j. The bucket count is an unspecified default value. The hash function is hasher(), and the key equality function is key_equal().
Range constructor with bucket count
X(i, j, n)
X a(i, j, n);
[i,j) is a valid range. Creates an associative container that contains all of the elements in the range [i,j) that have unique keys, using at least n buckets, and using hasher() as the hash function and key_equal() as the key equality function. size() is less than or equal to the distance from i to j. The bucket count is greater than or equal to n. The hash function is hasher(), and the key equality function is key_equal().
Range constructor with hash function
X(i, j, n, h)
X a(i, j, n, h);
[i,j) is a valid range. Creates an associative container that contains all of the elements in the range [i,j) that have unique keys, using at least n buckets, and using h as the hash function and key_equal() as the key equality function. size() is less than or equal to the distance from i to j. The bucket count is greater than or equal to n. The hash function is h, and the key equality function is key_equal().
Range constructor with key equal
X(i, j, n, h, k)
X a(i, j, n, h, k);
[i,j) is a valid range. Creates an associative container that contains all of the elements in the range [i,j) that have unique keys, using at least n buckets, and using h as the hash function and k as the key equality function. size() is less than or equal to the distance from i to j. The bucket count is greater than or equal to n. The hash function is h, and the key equality function is k.

Complexity guarantees

The range constructor, range constructor with bucket count, range constructor with hash function, and range constructor with key equal, are all linear in j - i.

Invariants

Models

  • hash_set
  • hash_map

Notes

[1] At present (early 1998), not all compilers support "member templates". If your compiler supports member templates then i and j may be of any type that conforms to the Input Iterator requirements. If your compiler does not yet support member templates, however, then i and j must be of type const T* or of type X::const_iterator.

See also

Associative Container, Hashed Associative Container, Multiple Hashed Associative Container Sorted Associative Container


Unique Sorted Associative Container

Category: containers | Component type: concept

Description

A Unique Sorted Associative Container is a Sorted Associative Container that is also a Unique Associative Container. That is, it is a Sorted Associative Container with the property that no two elements in the container have the same key.

Refinement of

Sorted Associative Container, Unique Associative Container

Associated types

None, except for those described in the Sorted Associative Container and Unique Associative Container requirements.

Notation

X | A type that is a model of Unique Sorted Associative Container
a | Object of type X
t | Object of type X::value_type
k | Object of type X::key_type
p, q | Object of type X::iterator
c | Object of type X::key_compare

Definitions

Valid expressions

In addition to the expressions defined in Sorted Associative Container and Unique Associative Container, the following expressions must be valid.
Name | Expression | Type requirements | Return type
Range constructor
X(i, j)
X a(i, j);
i and j are Input Iterators whose value type is convertible to T [1].
Range constructor with compare

X(i, j, c)
X a(i, j, c);
i and j are Input Iterators whose value type is convertible to T [1]. c is an object of type key_compare.
Insert with hint | a.insert(p, t) | iterator
Insert range | a.insert(i, j) | i and j are Input Iterators whose value type is convertible to X::value_type. [1] | void

Expression semantics

Name | Expression | Precondition | Semantics | Postcondition
Range constructor
X(i, j)
X a(i, j);
[i,j) is a valid range. Creates an associative container that contains all of the elements in the range [i,j) that have unique keys. The comparison object used by the container is key_compare(). size() is less than or equal to the distance from i to j.
Range constructor with compare

X(i, j, c)
X a(i, j, c);
[i,j) is a valid range. Creates an associative container that contains all of the elements in the range [i,j) that have unique keys. The comparison object used by the container is c. size() is less than or equal to the distance from i to j.
Insert with hint | a.insert(p, t) | p is a nonsingular iterator in a. | Inserts t into a if and only if a does not already contain an element whose key is equivalent to t's key. The argument p is a hint: it points to the location where the search will begin. The return value is a dereferenceable iterator that points to the element with a key that is equivalent to that of t. | a contains an element whose key is the same as that of t. The size of a is incremented by either 1 or 0.
Insert range | a.insert(i, j) | [i, j) is a valid range. | Equivalent to a.insert(t) for each object t that is pointed to by an iterator in the range [i, j). Each element is inserted into a if and only if a does not already contain an element with an equivalent key. | The size of a is incremented by at most j - i.

Complexity guarantees

The range constructor, and range constructor with compare, are in general O(N * log(N)), where N is the size of the range. However, they are linear in N if the range is already sorted by value_comp().

Insert with hint is logarithmic in general, but it is amortized constant time if t is inserted immediately before p.

Insert range is in general O(N * log(N)), where N is the size of the range. However, it is linear in N if the range is already sorted by value_comp().

Invariants

Strictly ascending order The elements in a Unique Sorted Associative Container are always arranged in strictly ascending order by key. That is, if a is a Unique Sorted Associative Container, then is_sorted(a.begin(), a.end(), a.value_comp()) is always true. Furthermore, if i and j are dereferenceable iterators in a such that i precedes j, then a.value_comp()(*i, *j) is always true. [2]

Models

  • map
  • set

Notes

[1] At present (early 1998), not all compilers support "member templates". If your compiler supports member templates then i and j may be of any type that conforms to the Input Iterator requirements. If your compiler does not yet support member templates, however, then i and j must be of type const T* or of type X::const_iterator.

[2] This is a more stringent invariant than that of Sorted Associative Container. In a Sorted Associative Container we merely know that every element is less than or equal to its successor; in a Unique Sorted Associative Container, however, we know that it must be less than its successor.

See also

Associative Container, Sorted Associative Container, Multiple Sorted Associative Container, Hashed Associative Container


unique_copy

Category: algorithms | Component type: function

Prototype

Unique_copy is an overloaded name; there are actually two unique_copy functions.
template <class InputIterator, class OutputIterator>
OutputIterator unique_copy(InputIterator first, InputIterator last,
                           OutputIterator result);

template <class InputIterator, class OutputIterator, class BinaryPredicate>
OutputIterator unique_copy(InputIterator first, InputIterator last,
                           OutputIterator result,
                           BinaryPredicate binary_pred);

Description

Unique_copy copies elements from the range [first, last) to a range beginning with result, except that in a consecutive group of duplicate elements only the first one is copied. The return value is the end of the range to which the elements are copied. This behavior is similar to the Unix filter uniq.

The reason there are two different versions of unique_copy is that there are two different definitions of what it means for a consecutive group of elements to be duplicates. In the first version, the test is simple equality: the elements in a range [f, l) are duplicates if, for every iterator i in the range, either i == f or else *i == *(i-1). In the second, the test is an arbitrary Binary Predicate binary_pred: the elements in [f, l) are duplicates if, for every iterator i in the range, either i == f or else binary_pred(*i, *(i-1)) is true. [1]

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

For the first version:
  • InputIterator is a model of Input Iterator.
  • InputIterator's value type is Equality Comparable.
  • OutputIterator is a model of Output Iterator.
  • InputIterator's value type is convertible to a type in OutputIterator's set of value types.
For the second version:
  • InputIterator is a model of Input Iterator.
  • BinaryPredicate is a model of Binary Predicate. [2]
  • InputIterator's value type is convertible to first argument type and to BinaryPredicate's second argument type.
  • OutputIterator is a model of Output Iterator.
  • InputIterator's value type is convertible to a type in OutputIterator's set of value types.

Preconditions

  • [first, last) is a valid range.
  • There is enough space to hold all of the elements being copied. More formally, if there are n elements in the range [first, last) after duplicates are removed from consecutive groups, then [result, result + n) must be a valid range.

Complexity

Linear. Exactly last - first applications of operator== (in the case of the first version of unique) or of binary_pred (in the case of the second version), and at most last - first assignments.

Example

Print all of the numbers in an array, but only print the first one in a consecutive group of identical numbers.
const int A[] = {2, 7, 7, 7, 1, 1, 8, 8, 8, 2, 8, 8};
unique_copy(A, A + sizeof(A) / sizeof(int),
            ostream_iterator<int>(cout, " "));
// The output is "2 7 1 8 2 8".

Notes

[1] Strictly speaking, the first version of unique_copy is redundant: you can achieve the same functionality by using an object of class equal_to as the Binary Predicate argument. The first version is provided strictly for the sake of convenience: testing for equality is an important special case.

[2] BinaryPredicate is not required to be an equivalence relation. You should be cautious, though, about using unique_copy with a Binary Predicate that is not an equivalence relation: you could easily get unexpected results.

See also

Binary Predicate, unique, remove_copy, remove_copy_if, adjacent_find


upper_bound

Category: algorithms | Component type: function

Prototype

Upper_bound is an overloaded name; there are actually two upper_bound functions.
template <class ForwardIterator, class LessThanComparable>
ForwardIterator upper_bound(ForwardIterator first, ForwardIterator last,
                            const LessThanComparable& value);

template <class ForwardIterator, class T, class StrictWeakOrdering>
ForwardIterator upper_bound(ForwardIterator first, ForwardIterator last,
                            const T& value, StrictWeakOrdering comp);

Description

Upper_bound is a version of binary search: it attempts to find the element value in an ordered range [first, last) [1]. Specifically, it returns the last position where value could be inserted without violating the ordering. [2] The first version of upper_bound uses operator< for comparison, and the second uses the function object comp.

The first version of upper_bound returns the furthermost iterator i in [first, last) such that, for every iterator j in [first, i), value < *j is false.

The second version of upper_bound returns the furthermost iterator i in [first, last) such that, for every iterator j in [first, i), comp(value, *j) is false.

Definition

Defined in the standard header algorithm, and in the nonstandard backward-compatibility header algo.h.

Requirements on types

For the first version:
  • ForwardIterator is a model of Forward Iterator.
  • LessThanComparable is a model of LessThan Comparable.
  • The ordering on objects of type LessThanComparable is a strict weak ordering, as defined in the LessThan Comparable requirements.
  • ForwardIterator's value type is the same type as LessThanComparable.
For the second version:
  • ForwardIterator is a model of Forward Iterator.
  • StrictWeakOrdering is a model of Strict Weak Ordering.
  • ForwardIterator's value type is the same type as T.
  • ForwardIterator's value type is convertible to StrictWeakOrdering's argument type.

Preconditions

For the first version:
  • [first, last) is a valid range.
  • [first, last) is ordered in ascending order according to operator<. That is, for every pair of iterators i and j in [first, last) such that i precedes j, *j < *i is false.
For the second version:
  • [first, last) is a valid range.
  • [first, last) is ordered in ascending order according to the function object comp. That is, for every pair of iterators i and j in [first, last) such that i precedes j, comp(*j, *i) is false.

Complexity

The number of comparisons is logarithmic: at most log(last - first) + 1. If ForwardIterator is a Random Access Iterator then the number of steps through the range is also logarithmic; otherwise, the number of steps is proportional to last - first. [3]

Example

int main()
{
  int A[] = { 1, 2, 3, 3, 3, 5, 8 };
  const int N = sizeof(A) / sizeof(int);

  for (int i = 1; i <= 10; ++i) {
    int* p = upper_bound(A, A + N, i);
    cout << "Searching for " << i << ".  ";
    cout << "Result: index = " << p - A << ", ";
    if (p != A + N)
      cout << "A[" << p - A << "] == " << *p << endl;
    else
      cout << "which is off-the-end." << endl;
  }
}
The output is:
Searching for 1.  Result: index = 1, A[1] == 2
Searching for 2.  Result: index = 2, A[2] == 3
Searching for 3.  Result: index = 5, A[5] == 5
Searching for 4.  Result: index = 5, A[5] == 5
Searching for 5.  Result: index = 6, A[6] == 8
Searching for 6.  Result: index = 6, A[6] == 8
Searching for 7.  Result: index = 6, A[6] == 8
Searching for 8.  Result: index = 7, which is off-the-end.
Searching for 9.  Result: index = 7, which is off-the-end.
Searching for 10.  Result: index = 7, which is off-the-end.

Notes

[1] Note that you may use an ordering that is a strict weak ordering but not a total ordering; that is, there might be values x and y such that x < y, x > y, and x == y are all false. (See the LessThan Comparable requirements for a more complete discussion.) Finding value in the range [first, last), then, doesn't mean finding an element that is equal to value but rather one that is equivalent to value: one that is neither greater than nor less than value. If you're using a total ordering, however (if you're using strcmp, for example, or if you're using ordinary arithmetic comparison on integers), then you can ignore this technical distinction: for a total ordering, equality and equivalence are the same.

[2] Note that even if an element that is equivalent to [1] value is already present in the range [first, last), the return value of upper_bound will not point to that element. The return value is either last or else an iterator i such that value < *i. If i is not equal to first, however, then *(i - 1) is less than or equivalent to value.

[3] This difference between Random Access Iterators and Forward Iterators is simply because advance is constant time for Random Access Iterators and linear time for Forward Iterators.

See also

lower_bound, equal_range, binary_search


value_type

Category: iterators | Component type: function

Prototype

Value_type is overloaded; it is in fact five different functions.
template <class T, class Distance>
inline T* value_type(const input_iterator<T, Distance>&);

template <class T, class Distance>
inline T* value_type(const forward_iterator<T, Distance>&);

template <class T, class Distance>
inline T* value_type(const bidirectional_iterator<T, Distance>&);

template <class T, class Distance>
inline T* value_type(const random_access_iterator<T, Distance>&);

template <class T> inline T* value_type(const T*);

Description

Value_type is an iterator tag function: it is used to determine the value type associated with an iterator. An iterator's value type is the type of object returned when the iterator is dereferenced; Output Iterators do not have value types (Output Iterators may only be used for storing values, not for accessing values), but Input Iterators, Forward Iterators, Bidirectional Iterators, and Random Access Iterators do. [1] In some cases, such as an algorithm that must declare a local variable that holds a value returned from dereferencing an iterator, it is necessary to find out an iterator's value type. Accordingly, value_type(Iter) returns (T*) 0, where T is Iter's value type.

Although value_type looks like a single function whose return type depends on its argument type, in reality it is a set of functions; the name value_type is overloaded. The function value_type must be overloaded for every iterator type [1].

In practice, ensuring that value_type is defined requires essentially no work at all. It is already defined for pointers, and for the base classes input_iterator, forward_iterator, bidirectional_iterator, and random_access_iterator. If you are implementing a new type of forward iterator, for example, you can simply derive it from the base class forward_iterator; this means that value_type (along with iterator_category and distance_type) will automatically be defined for your iterator. These base classes are empty: they contain no member functions or member variables, but only type information. Using them should therefore incur no overhead.

Note that, while the function value_type was present in the original STL, it is no longer present in the most recent draft C++ standard: it has been replaced by the iterator_traits class At present both mechanisms are supported [2], but eventually value_type will be removed.

Definition

Defined in the standard header iterator, and in the nonstandard backward-compatibility header iterator.h. This function is no longer part of the C++ standard, although it was present in early drafts of the standard. It is retained in this implementation for backward compatibility.

Requirements on types

The argument of value_type must be an Input Iterator, Forward Iterator, Bidirectional Iterator, or Random Access Iterator. [1]

Preconditions

None. Value_type's argument is even permitted to be a singular iterator.

Complexity

At most amortized constant time. In many cases, a compiler should be able to optimize away value_type entirely.

Example

This example uses the value_type iterator tag function in order to declare a temporary variable of an iterator's value type.
template <class ForwardIterator1, class ForwardIterator2, class ValueType>
inline void __iter_swap(ForwardIterator1 a, ForwardIterator2 b, ValueType*) {
    T tmp = *a;
    *a = *b;
    *b = tmp;
}

template <class ForwardIterator1, class ForwardIterator2>
inline void iter_swap(ForwardIterator1 a, ForwardIterator2 b) {
    __iter_swap(a, b, value_type(a));
}

Notes

[1] Note that distance_type is not defined for Output Iterators or for Trivial Iterators. In the case of Output Iterators, this is because an Output Iterator does not have a value type: it is not possible to dereference an Output Iterator and obtain a value. In the case of Trivial Iterators, this is because the concept was introduced only for conceptual clarity, in order to separate the axioms related to an object that refers to another object from those related to iteration over a range. In fact, the STL does not define any types that are Trivial Iterators. Although built-in C pointers may be Trivial Iterators, the C type system does not allow a distinction between pointers that are Trivial Iterators and pointers that are Random Access Iterators into C arrays. Consequently, there is no Trivial Iterator category tag or iterator base.

[2] The iterator_traits class relies on a C++ feature known as partial specialization. Many of today's compilers don't implement the complete standard; in particular, many compilers do not support partial specialization. If your compiler does not support partial specialization, then you will not be able to use iterator_traits, and you will have to continue using the functions iterator_category, distance_type, and value_type. This is one reason that those functions have not yet been removed.

See also

The Iterator Tags overview, iterator_traits, iterator_category, distance_type, output_iterator_tag, input_iterator_tag, forward_iterator_tag, bidirectional_iterator_tag, random_access_iterator_tag


vector<T, Alloc>

Category: containers | Component type: type

Description

A vector is a Sequence that supports random access to elements, constant time insertion and removal of elements at the end, and linear time insertion and removal of elements at the beginning or in the middle. The number of elements in a vector may vary dynamically; memory management is automatic. Vector is the simplest of the STL container classes, and in many cases the most efficient.

Example

vector<int> V;
V.insert(V.begin(), 3);
assert(V.size() == 1 && V.capacity() >= 1 && V[0] == 3);

Definition

Defined in the standard header vector, and in the nonstandard backward-compatibility header vector.h.

Template parameters

Parameter | Description | Default
T | The vector's value type: the type of object that is stored in the vector. |
Alloc | The vector's allocator, used for all internal memory management. | alloc

Model of

Random Access Container, Back Insertion Sequence.

Type requirements

None, except for those imposed by the requirements of Random Access Container and Back Insertion Sequence.

Public base classes

None.

Members

Member | Where defined | Description
value_type | Container | The type of object, T, stored in the vector.
pointer | Container | Pointer to T.
reference | Container | Reference to T
const_reference | Container | Const reference to T
size_type | Container | An unsigned integral type.
difference_type | Container | A signed integral type.
iterator | Container | Iterator used to iterate through a vector.
const_iterator | Container | Const iterator used to iterate through a vector.
reverse_iterator | Reversible Container | Iterator used to iterate backwards through a vector.
const_reverse_iterator | Reversible Container | Const iterator used to iterate backwards through a vector.
iterator begin() | Container | Returns an iterator pointing to the beginning of the vector.
iterator end() | Container | Returns an iterator pointing to the end of the vector.
const_iterator begin() const | Container | Returns a const_iterator pointing to the beginning of the vector.
const_iterator end() const | Container | Returns a const_iterator pointing to the end of the vector.
reverse_iterator rbegin() | Reversible Container | Returns a reverse_iterator pointing to the beginning of the reversed vector.
reverse_iterator rend() | Reversible Container | Returns a reverse_iterator pointing to the end of the reversed vector.
const_reverse_iterator rbegin() const | Reversible Container | Returns a const_reverse_iterator pointing to the beginning of the reversed vector.
const_reverse_iterator rend() const | Reversible Container | Returns a const_reverse_iterator pointing to the end of the reversed vector.
size_type size() const | Container | Returns the size of the vector.
size_type max_size() const | Container | Returns the largest possible size of the vector.
size_type capacity() const | vector | See below.
bool empty() const | Container | true if the vector's size is 0.
reference operator[](size_type n) | Random Access Container | Returns the n'th element.
const_reference operator[](size_type n) const | Random Access Container | Returns the n'th element.
vector() | Container | Creates an empty vector.
vector(size_type n) | Sequence | Creates a vector with n elements.
vector(size_type n, const T& t) | Sequence | Creates a vector with n copies of t.
vector(const vector&) | Container | The copy constructor.
template <class InputIterator>
vector(InputIterator, InputIterator)
[1]
Sequence Creates a vector with a copy of a range.
~vector() | Container | The destructor.
vector& operator=(const vector&) | Container | The assignment operator
void reserve(size_t) | vector | See below.
reference front() | Sequence | Returns the first element.
const_reference front() const | Sequence | Returns the first element.
reference back() | Back Insertion Sequence | Returns the last element.
const_reference back() const | Back Insertion Sequence | Returns the last element.
void push_back(const T&) | Back Insertion Sequence | Inserts a new element at the end.
void pop_back() | Back Insertion Sequence | Removes the last element.
void swap(vector&) | Container | Swaps the contents of two vectors.
iterator insert(iterator pos,
                const T& x)
Sequence Inserts x before pos.
template <class InputIterator>
void insert(iterator pos,
            InputIterator f, InputIterator l)
[1]
Sequence Inserts the range [first, last) before pos.
void insert(iterator pos,
            size_type n, const T& x)
Sequence Inserts n copies of x before pos.
iterator erase(iterator pos) | Sequence | Erases the element at position pos.
iterator erase(iterator first, iterator last) | Sequence | Erases the range [first, last)
void clear() | Sequence | Erases all of the elements.
void resize(n, t = T()) | Sequence | Inserts or erases elements at the end such that the size becomes n.
bool operator==(const vector&,
                const vector&)
Forward Container Tests two vectors for equality. This is a global function, not a member function.
bool operator<(const vector&,
               const vector&)
Forward Container Lexicographical comparison. This is a global function, not a member function.

New members

These members are not defined in the Random Access Container and Back Insertion Sequence requirements, but are specific to vector.
Member | Description
size_type capacity() const | Number of elements for which memory has been allocated. capacity() is always greater than or equal to size(). [2] [3]
void reserve(size_type n) | If n is less than or equal to capacity(), this call has no effect. Otherwise, it is a request for allocation of additional memory. If the request is successful, then capacity() is greater than or equal to n; otherwise, capacity() is unchanged. In either case, size() is unchanged. [2] [4]

Notes

[1] This member function relies on member template functions, which at present (early 1998) are not supported by all compilers. If your compiler supports member templates, you can call this function with any type of input iterator. If your compiler does not yet support member templates, though, then the arguments must be of type const value_type*.

[2] Memory will be reallocated automatically if more than capacity() - size() elements are inserted into the vector. Reallocation does not change size(), nor does it change the values of any elements of the vector. It does, however, increase capacity(), and it invalidates [5] any iterators that point into the vector.

[3] When it is necessary to increase capacity(), vector usually increases it by a factor of two. It is crucial that the amount of growth is proportional to the current capacity(), rather than a fixed constant: in the former case inserting a series of elements into a vector is a linear time operation, and in the latter case it is quadratic.

[4] Reserve() causes a reallocation manually. The main reason for using reserve() is efficiency: if you know the capacity to which your vector must eventually grow, then it is usually more efficient to allocate that memory all at once rather than relying on the automatic reallocation scheme. The other reason for using reserve() is so that you can control the invalidation of iterators. [5]

[5] A vector's iterators are invalidated when its memory is reallocated. Additionally, inserting or deleting an element in the middle of a vector invalidates all iterators that point to elements following the insertion or deletion point. It follows that you can prevent a vector's iterators from being invalidated if you use reserve() to preallocate as much memory as the vector will ever use, and if all insertions and deletions are at the vector's end.

See also

deque, list, slist


STL: What's New

 SGI

What's New

Release 3.3: June 8, 2000

  • New feature: concept checks. The library now does better compile-time error checking to make sure that the types used to instantiate library templates conform to the templates' requirements.
  • Removed two non-standard-conforming extensions: the second, defaulted template parameter in bitset, and the third, default template parameter in deque.
  • Many bug fixes, performance enhancements, and compatibility improvements.

Release 3.2: April 22, 1999

  • New feature: <valarray> header, as defined in section 26.3 of the C++ standard.
  • <limits> header is now supported on compilers that lack support for constant initialization of static const data members, such as Microsoft v6.0.
  • Performance improvements in copy for compilers that lack support for partial specialization of templates.
  • Improved support for insert_iterator when used with hash tables and slist.
  • Documentation bug fix: documentation now makes it clear which library features are standard and which are SGI extensions.
  • Bug fixes.

Release 3.13: March 11, 1999

  • Added a Frequently Asked Questions list.
  • Bug fixes, particularly in multithreading support for non-SGI compilers.
  • The at member function is now supported for the vector and deque classes. (It was previously supported only for string.)

Release 3.12: February 2, 1999

  • Minor bug fixes.
  • The <string> and <bitset> headers are now supported on compilers that lack full support for member templates and partial specialization, such as Microsoft v6.0.
  • Code to support multithreading has been consolidated in a single file, so that system dependences are better isolated.

Release 3.11: July 21, 1998

  • Minor bug fixes.
  • Faster operator[] in map.
  • Algorithmic improvements in find, find_if, and partition.
  • The standard exception hierarchy is now usable on compilers that do not provide an <exception> header.

Release 3.1: June 9, 1998

This release provides several new features.
  • Standard-conforming string and bitset classes, and the standard exception hierarchy.
  • Standard-conforming allocators, including the default allocator class allocator<T>. All containers now use standard allocators, and all containers now support allocators whose instances are distinct. Old-style allocators, like alloc, are still supported for backward compatibility.
  • Algorithmic improvements in search.
  • All sequences now support the resize and assign member functions. All sequences now properly support overloaded insert member functions and constructors in the presence of member templates.
  • Bug fixes in rope, and minor bug fixes elsewhere. Minor changes for standard conformance.
  • Standard-conforming auto_ptr class.
  • Internal names, such as names of function and template parameters, have been changed so that they cannot conflict with user names (including user macros).

Release 3.01: October 31, 1997

This is a minor release. It consists only of bug fixes (the most important ones are in rope), small changes to reflect changes in the Final Draft International Standard (FDIS), and performance improvements in single-element insertion into containers.

Release 3.0: October 31, 1997

  • Major reorganization of header files. Headers now have the names described in the draft C++ standard. (Old header names are provided as well for backward compatibility.) The new-style headers declare their contents in namespace std; the old-style headers do too, but they import those declarations into the global namespace with using declarations. So, for example, #include <vector.h> is roughly equivalent to #include <vector> followed by the declaration using std::vector;.

    Note that namespace std is only enabled for compilers whose support for namespaces is sufficient; this is controlled by the header <stl_config.h>.

  • Bug fixes, and minor changes for standard conformance.

Release 2.03: September 9, 1997

  • Bug fixes, most importantly in rope.
  • New version of reverse_iterator that takes only a single template parameter, as described in the draft standard. (This relies on iterator_traits, so you can only use the new version of reverse_iterator if your compiler supports partial specialization.)
  • New algorithms: find_first_of, search_n, find_end
  • Changed the iterator tag classes so that they form an inheritance hierarchy.
  • Added the -> operator to all predefined iterators (except for output iterators).

Release 2.02: July 31, 1997

  • Bug fixes, most importantly in rope and deque.
  • New feature: function object adaptors for member functions. This is a family of classes: mem_fun_t, mem_fun_ref_t, mem_fun1_t, mem_fun1_ref_t.

Release 2.01: June 30, 1997

Bug fixes only, no new features.

Release 2.0: June 13, 1997

This is a major release, with many new features. Here are some of the most important.
  • Exception safety. All STL components are now exception safe.
  • New container class: rope. A scalable string representation.
  • New container class: slist. Singly linked lists.
  • Member templates. If your compiler supports member templates, then you will be able to use the fully general form of containers' copy constructors and insert member functions.
  • New mechanism for accessing iterators' associated type information: iterator_traits. (Note: you can only use iterator_traits if your compiler supports "partial specialization".) The algorithms count, count_if, and distance have been rewritten in terms of iterator_traits.
  • Reimplementation of deque. deque has been completely rewritten, for higher performance.
  • type_traits mechanism, which allows omission of null constructor and destructor calls.
  • New temporary_buffer class. This was partially motivated by exception safety, but it is also more convenient and more efficient than the old get_temporary_buffer and return_temporary_buffer functions.
  • New allocator, debug_alloc, which is useful for verifying the correctness of memory allocation and deallocation.
  • New algorithms: copy_n, lexicographical_compare_3way, power, uninitialized_copy_n.
  • Greater portability. The SGI STL can now be compiled using Microsoft Visual C++ 5.0, and Borland C++ 5.02; it should not be difficult to port it to any other compiler that has good support for templates. (Specifically, any compiler that has default template parameters.) Most compiler-specific code is isolated in the file stl_config.h.